I'm trying to figure out the best way to handle requests to /
and only /
in Go and handle different methods in different ways. Here's the best I've come up with:
package main import ( "fmt" "html" "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } if r.Method == "GET" { fmt.Fprintf(w, "GET, %q", html.EscapeString(r.URL.Path)) } else if r.Method == "POST" { fmt.Fprintf(w, "POST, %q", html.EscapeString(r.URL.Path)) } else { http.Error(w, "Invalid request method.", 405) } }) log.Fatal(http.ListenAndServe(":8080", nil)) }
Is this idiomatic Go? Is this the best I can do with the standard http lib? I'd much rather do something like http.HandleGet("/", handler)
as in express or Sinatra. Is there a good framework for writing simple REST services? web.go looks attractive but appears stagnant.
Thank you for your advice.
The primary or most commonly-used HTTP methods are POST, GET, PUT, PATCH, and DELETE.
Strictly speaking, what we mean by handler is an object which satisfies the http.Handler interface: type Handler interface { ServeHTTP(ResponseWriter, *Request) } In simple terms, this basically means that to be a handler an object must have a ServeHTTP() method with the exact signature: ServeHTTP(http.
The HttpServlet class provides specialized methods that handle the various types of HTTP requests. A servlet developer typically overrides one of these methods. These methods are doDelete( ), doGet( ), doHead( ), doOptions( ), doPost( ), doPut( ), and doTrace( ).
To ensure that you only serve the root: You're doing the right thing. In some cases you would want to call the ServeHttp method of an http.FileServer object instead of calling NotFound; it depends whether you have miscellaneous files that you want to serve as well.
To handle different methods differently: Many of my HTTP handlers contain nothing but a switch statement like this:
switch r.Method { case http.MethodGet: // Serve the resource. case http.MethodPost: // Create a new record. case http.MethodPut: // Update an existing record. case http.MethodDelete: // Remove the record. default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) }
Of course, you may find that a third-party package like gorilla works better for you.
eh, I was actually heading to bed and thus the quick comment on looking at http://www.gorillatoolkit.org/pkg/mux which is really nice and does what you want, just give the docs a look over. For example
func main() { r := mux.NewRouter() r.HandleFunc("/", HomeHandler) r.HandleFunc("/products", ProductsHandler) r.HandleFunc("/articles", ArticlesHandler) http.Handle("/", r) }
and
r.HandleFunc("/products", ProductsHandler). Host("www.domain.com"). Methods("GET"). Schemes("http")
and many other possibilities and ways to perform the above operations.
But I felt a need to address the other part of the question, "Is this the best I can do". If the std lib is a little too bare, a great resource to check out is here: https://github.com/golang/go/wiki/Projects#web-libraries (linked specifically to web libraries).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With