162

I'm using the httppackage from Go to deal with POST request. How can I access and parse the content of the query string from the Requestobject ? I can't find the answer from the official documentation.

Fabien
  • 12,486
  • 9
  • 44
  • 62
  • One thing to keep in mind, if you're using cURL to send requests and you use `r.FormValue("id")` to fetch a query param, you can't send i through form data in cURL (ie, `curl 0.0.0.0:8888 -d id=foobar` will not work). You must send it via query params (`curl 0.0.0.0:8888?id=foobar`). –  Oct 26 '15 at 12:14

6 Answers6

186

Here's a more concrete example of how to access GET parameters. The Request object has a method that parses them out for you called Query:

Assuming a request URL like http://host:port/something?param1=b

func newHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("GET params were:", r.URL.Query())

  // if only one expected
  param1 := r.URL.Query().Get("param1")
  if param1 != "" {
    // ... process it, will be the first (only) if multiple were given
    // note: if they pass in like ?param1=&param2= param1 will also be "" :|
  }

  // if multiples possible, or to process empty values like param1 in
  // ?param1=&param2=something
  param1s := r.URL.Query()["param1"]
  if len(param1s) > 0 {
    // ... process them ... or you could just iterate over them without a check
    // this way you can also tell if they passed in the parameter as the empty string
    // it will be an element of the array that is the empty string
  }    
}

Also note "the keys in a Values map [i.e. Query() return value] are case-sensitive."

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
  • 4
    A [previous answer](http://stackoverflow.com/a/15408779/55504) already mentioned and linked to the docs of doing just that (and it doesn't have an example that will panic with an out of bounds slice reference if the desired field isn't present, use `r.URL.Query().Get("moviename")` to avoid this fatal mistake). – Dave C Mar 24 '15 at 20:01
  • 2
    Thanks for the info. Yeah, the docs are a bit confusing for me, so I posted this as more of a "hands on example" in case useful. Fixed the nil check. Using the `Get` method only returns the first if there are multiple, so this is an example of more. Useful info, thank you! – rogerdpack Mar 24 '15 at 21:31
  • Also I don't think you can compare a string to nil : http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/ i.e. string != "" is valid – James Milner Jan 09 '16 at 22:13
  • I don't think that code would compile, were the example complete. You can't compare the empty string that `Values.Get()` returns with `nil`. https://golang.org/pkg/net/url/#Values – erik258 Aug 11 '18 at 02:56
180

A QueryString is, by definition, in the URL. You can access the URL of the request using req.URL (doc). The URL object has a Query() method (doc) that returns a Values type, which is simply a map[string][]string of the QueryString parameters.

If what you're looking for is the POST data as submitted by an HTML form, then this is (usually) a key-value pair in the request body. You're correct in your answer that you can call ParseForm() and then use req.Form field to get the map of key-value pairs, but you can also call FormValue(key) to get the value of a specific key. This calls ParseForm() if required, and gets values regardless of how they were sent (i.e. in query string or in the request body).

mna
  • 22,989
  • 6
  • 46
  • 49
  • 2
    I find the 'req.FormValue(key)' method more faster and do for you all the needed code to pre parse the url. – OnlyAngel May 23 '14 at 01:44
  • 10
    `req.URL.RawQuery` returns everything after the `?` on a GET request, if that helps. – kouton Aug 01 '14 at 09:14
  • I found it interesting req.Form is empty array unless req.formValue("some_field") is invoked at lease once. –  Jun 21 '15 at 14:51
21

Below is an example:

value := r.FormValue("field")

for more info. about http package, you could visit its documentation here. FormValue basically returns POST or PUT values, or GET values, in that order, the first one that it finds.

Edson Medina
  • 9,862
  • 3
  • 40
  • 51
Muhammad Soliman
  • 21,644
  • 6
  • 109
  • 75
10

There are two ways of getting query params:

  1. Using reqeust.URL.Query()
  2. Using request.Form

In second case one has to be careful as body parameters will take precedence over query parameters. A full description about getting query params can be found here

https://golangbyexample.com/net-http-package-get-query-params-golang

user27111987
  • 995
  • 2
  • 10
  • 26
9

Here's a simple, working example:

package main

import (
    "io"
    "net/http"
)
func queryParamDisplayHandler(res http.ResponseWriter, req *http.Request) {
    io.WriteString(res, "name: "+req.FormValue("name"))
    io.WriteString(res, "\nphone: "+req.FormValue("phone"))
}

func main() {
    http.HandleFunc("/example", func(res http.ResponseWriter, req *http.Request) {
        queryParamDisplayHandler(res, req)
    })
    println("Enter this in your browser:  http://localhost:8080/example?name=jenny&phone=867-5309")
    http.ListenAndServe(":8080", nil)
}

enter image description here

l3x
  • 30,760
  • 1
  • 55
  • 36
6

Below words come from the official document.

Form contains the parsed form data, including both the URL field's query parameters and the POST or PUT form data. This field is only available after ParseForm is called.

So, sample codes as below would work.

func parseRequest(req *http.Request) error {
    var err error

    if err = req.ParseForm(); err != nil {
        log.Error("Error parsing form: %s", err)
        return err
    }

    _ = req.Form.Get("xxx")

    return nil
}
ChrisLee
  • 99
  • 1
  • 4