HTTP parameter passing in Golang

Preface

In HTTP API design, how parameters are passed is quite important. Let’s see the way how to do it in Golang.

The Way HTTP do it

There are mainly 3 ways to pass data when HTTP:

  • encode in url parameters:
    1
    http://foo.com/login?name=joe&dob=19650203
  • In url path, RESTful way:
    1
    2
    # get all articles under health tag and set date
    GET http://foo.com/articles/{health}/{date}
  • In JSON body
    1
    2
    3
    4
    {
    "id" : "123",
    "name" : "frank"
    }

How to pass in Golang

following illustration will be using github.com/gorilla/mux to build HTTP server:

1
2
3
4
5
6
7
8
9
10
import "github.com/gorilla/mux"

func NewRouter() http.Handler {
router := mux.NewRouter()

router.HandleFunc("/", action.Index).Methods("GET")
router.HandleFunc("/v1/trip_info/{date}/count", action.GetCabsPickupCountInfo).Methods("POST")
router.HandleFunc("/v1/trip_info/update_cache", action.UpdateCache).Methods("PUT")
return router
}
Pass in URL parameters

pass name and D.O.B like following

1
http://foo.com/login?name=joe&dob=19650203

parse data in parameters:

1
2
3
4
func Login(res http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get("name")
dob := req.URL.Query().Get("dob")
}
Pass in URL path

pass in URL path, following is how to pass date:

1
/v1/trip_info/{date}/count
1
2
3
4
func GetCabsPickupCountInfo(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
callID := vars["date"]
}
Pass in JSON Body

We can also pass parameters in HTTP body using JSON:

in data.json file

1
2
3
4
5
6
7
{
"id": "1",
"date" : "2018-08-11",
"tags" : ["health", "sports"],
"title" : "article 1 changed by frank",
"body" : "article 1 body"
}

Following command will invoke article_service/articles/create API, passing json in HTTP body

1
curl -XPOST http://article_service/articles/create -d@data.json

using following code to parse data from HTTP JSON body:

  • Create a construct to unmarshal json

    1
    2
    3
    4
    5
    6
    7
    type Article struct {
    Id string `json:"id"`
    Title string `json:"title"`
    Date string `json:"date"`
    Body string `json:"body"`
    Tags []string `json:"tags"`
    }
  • Parse HTTP Body

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const (
    maxBodyLength = 1000
    )
    func ArticleUpsert(res http.ResponseWriter, req *http.Request) {
    // in case coming request is too large
    req.Body = http.MaxBytesReader(res, req.Body, maxBodyLength)
    body, err := ioutil.ReadAll(req.Body)
    if err != nil {
    log.Error(err)
    return
    }
    var article Article
    err = json.Unmarshal(body, &article)
    if err != nil {
    ...
    }
    ...
    }

Conclusion

In this blog we see 3 different ways to get data in HTTP by Golang; In a lot of browsers, url length may have limit

URLs over 2,000 characters will not work in the most popular web browsers.

So if it is required to pass more data, pass in HTTP body may be a better choice, there is no limit by specification, but server or client have different limitations about it.

Reference

What is the maximum length of a URL in different browsers?
What is the size limit of a post request?