Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I handle http requests of different methods to / in Go?

Tags:

go

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.

like image 723
Trevor Dixon Avatar asked Mar 06 '13 06:03

Trevor Dixon


People also ask

What are the 4 types of HTTP request methods?

The primary or most commonly-used HTTP methods are POST, GET, PUT, PATCH, and DELETE.

What is HTTP handler go?

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.

How do you handle HTTP requests and responses?

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( ).


2 Answers

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.

like image 141
andybalholm Avatar answered Sep 28 '22 14:09

andybalholm


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).

like image 43
dskinner Avatar answered Sep 28 '22 13:09

dskinner