Receiving Data from GET and POST Requests
An HTTP client can send data to an HTTP server along with an HTTP request. Typical examples of this include:
Submitting a form
Setting options on data to be returned
Managing data through an API interface
Getting data from a client request is simple in Go, but depending on the type of request it is accessed in different ways. For a GET, request data is usually set through a query string. An example of sending data through a GET request is making a search on Google. Here, the URL includes a search term as a query string:
https://www.google.com/?q=golang
A web server may then read in the query string data, using it to do something like fetch some data from a database before returning it to the client. In Go, the query string parameters for a request are available as a map of strings, and these can be iterated over using a range clause.
func queryParams(w http.ResponseWriter, r *http.Request) { for k, v := range r.URL.Query() { fmt.Printf("%s: %s\n", k, v) } }
For a POST request, data is usually sent as the body of a request. This data may be read and used as follows:
func queryParams(w http.ResponseWriter, r *http.Request) { reqBody, err := ioutil.ReadAll(r.Body) if err != nil { log.Fatal(err) } fmt.Printf("%s", reqBody) }
A full code example can now be created to demonstrate handling data from different requests, which appears in Listing 18.6. This server builds on the previous example to show the data that is sent to the server. Running this example shows that data can be received for different types of requests. Of course, the server will probably want to do something more interesting with the data other than return it to the client.
LISTING 18.6 Handling Data from Different Requests
1: package main 2: 3: import ( 4: "fmt" 5: "io/ioutil" 6: "log" 7: "net/http" 8: ) 9: 10: func helloWorld(w http.ResponseWriter, r *http.Request) { 11: if r.URL.Path != "/" { 12: http.NotFound(w, r) 13: return 14: } 15: switch r.Method { 16: case "GET": 17: for k, v := range r.URL.Query() { 18: fmt.Printf("%s: %s\n", k, v) 19: } 20: w.Write([]byte("Received a GET request\n")) 21: case "POST": 22: reqBody, err := ioutil.ReadAll(r.Body) 23: if err != nil { 24: log.Fatal(err) 25: } 26: 27: fmt.Printf("%s\n", reqBody) 28: w.Write([]byte("Received a POST request\n")) 29: default: 30: w.WriteHeader(http.StatusNotImplemented) 31: w.Write([]byte(http.StatusText(http.StatusNotImplemented))) 32: } 33: 34: } 35: 36: func main() { 37: http.HandleFunc("/", helloWorld) 38: http.ListenAndServe(":8000", nil) 39: }