rodrigosaito.com

home

Rest API with gorilla/mux routing

04 May 2015

Go standard library has a lot of useful packages, but for creating routes on your API other packages are a better fit. In this tutorial we will use gorilla/mux package as our request router.

You can find the documentation for gorilla/mux here

First let's modify our previous example to have two different handler functions, one for GET and one for POST, instead of one for both requests. You can find the previous post here.

 1 func getMembersHandler(w http.ResponseWriter, r *http.Request) {
 2         w.Header().Set("Content-Type", "application/json")
 3 
 4         j, _ := json.Marshal(members)
 5         w.Write(j)
 6 }
 7 
 8 func postMembersHandler(w http.ResponseWriter, r *http.Request) {
 9         w.Header().Set("Content-Type", "application/json")
10 
11         var m Member
12         b, _ := ioutil.ReadAll(r.Body)
13         json.Unmarshal(b, &m)
14 
15         members = append(members, m)
16 
17         j, _ := json.Marshal(m)
18         w.Write(j)
19 }

Now we have two different functions for handling two different requests GET /members and POST /members, the main advantage of this refactoring is that we can now test the functions separately, I will show you how to test your handler functions on a future post.

And here is the new main() function:

1 func main() {
2         r := mux.NewRouter()
3         r.HandleFunc("/members", getMembersHandler).Methods("GET")
4         r.HandleFunc("/members", postMembersHandler).Methods("POST")
5 
6         http.Handle("/", r)
7         http.ListenAndServe(":8080", nil)
8 }

Explanations:

The package gorilla/mux has a lot of different ways to match requests, check the documentation for more information.

Here is the full example:

 1 package main
 2 
 3 import (
 4         "encoding/json"
 5         "io/ioutil"
 6         "net/http"
 7 
 8         "github.com/gorilla/mux"
 9 )
10 
11 var members = []Member{Member{"someuser", "someuser@somedomain.com"}}
12 
13 type Member struct {
14         Login string
15         Email string
16 }
17 
18 func getMembersHandler(w http.ResponseWriter, r *http.Request) {
19         w.Header().Set("Content-Type", "application/json")
20 
21         j, _ := json.Marshal(members)
22         w.Write(j)
23 }
24 
25 func postMembersHandler(w http.ResponseWriter, r *http.Request) {
26         w.Header().Set("Content-Type", "application/json")
27 
28         var m Member
29         b, _ := ioutil.ReadAll(r.Body)
30         json.Unmarshal(b, &m)
31 
32         members = append(members, m)
33 
34         j, _ := json.Marshal(m)
35         w.Write(j)
36 }
37 
38 func main() {
39         r := mux.NewRouter()
40         r.HandleFunc("/members", getMembersHandler).Methods("GET")
41         r.HandleFunc("/members", postMembersHandler).Methods("POST")
42 
43         http.Handle("/", r)
44         http.ListenAndServe(":8080", nil)
45 }