Golang Mux Router

Golang REST API

Welcome to the second section of the Golang REST API tutorial, where we code from scratch in Go everything needed. If you haven’t checked out the first segment, go to Golang REST API. So keep the flow going.

In the last article, we learned how to create the basic structure of our server, and making a database of 3 books with the properties – Title, Author, and Link. Now the standard library is adequate at providing everything you need to get your own simple REST API up and running, and then we are introducing the most notable and highly used third-party router package called gorilla/mux router. It has 12800 stars on Github!

Table of Contents

Mux Router

It implements a request router and dispatcher for matching incoming requests to their respective handler.

The name mux stands for “HTTP request multiplexer”. Like the standard http.ServeMux, mux.Router matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions.

Open the main.go file again, and we’ll make some modifications:

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

...

func handleRequests() {
	myRouter := mux.NewRouter().StrictSlash(true)
	myRouter.HandleFunc("/", homePage)
	myRouter.HandleFunc("/articles", returnAllArticles)
	log.Fatal(http.ListenAndServe(":8000", myRouter))
}
...

We’ve now changed the import function to include our gorilla/mux package. If you get an error, you will need to install it first:

go get -u github.com/gorilla/mux
  • We create a new instance of the mux router called myRouter, and enable “StrictSlash” that redirects “localhost:8000/articles/” to “localhost:8000/articles”.
  • Then we replace http.HandleFunc with myRouter.HandleFunc
  • And then we pass our new router to listenAndServe.

If we go run main.go, you’ll not see any visual change in the output. The difference, however, is that we now have it on gorilla/mux.

Congrats. We’ve created a very simple REST API that returns a homepage and all our articles.

Adding id and path

Now, let’s add the functionality of separately fetching these articles by an id that we can define in the url itself:

Add ID property to the Article struct:

type Article struct {
	ID     string `json:"Id"`
	Title  string `json:"Title"`
	Author string `json:"author"`
	Link   string `json:"link"`
}

Then in the handleRequests function, add a new url path:

myRouter.HandleFunc("/article/{id}",returnSingleArticle)

Then we need to create this returnSingleArticle function:

func returnSingleArticle(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	key := vars["id"]

	for _, article := range Articles {
		if article.ID == key {
			json.NewEncoder(w).Encode(article)
		}
	}
}

That’s it. Now if we go to the url http://localhost:8000/article/2, we get:

Return Single Article Golang Rest Api
Return Single Article Golang Rest Api

REST Client Requests using Postman

There is a very handy Chrome application called Postman that can be used to manually send POST and GET requests to our server. We’ll simply add another line within handleRequests function:

myRouter.HandleFunc("/article", createNewArticle).Methods("POST")

And then add a new function createNewArticle:

func createNewArticle(w http.ResponseWriter, r *http.Request) {
    reqBody, _ := ioutil.ReadAll(r.Body)
    var article Article 
    json.Unmarshal(reqBody, &article)
    Articles = append(Articles, article)

    json.NewEncoder(w).Encode(article)
}

This allows us to pass json formats to add new articles to our database.

Delete function

We learned how to create, so now it is obvious to know how to delete them too. For this we add another line to handleRequests function:

myRouter.HandleFunc("/article/{id}", deleteArticle).Methods("DELETE")

and then similarly, create the deleteArticle function:

func deleteArticle(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]

    for index, article := range Articles {
        if article.Id == id {
            Articles = append(Articles[:index], Articles[index+1:]...)
        }
    }

}

We’ll again use Postman – this time we send a DELETE request to http://localhost:8000/article/2, and this will remove that entry from our database.

That brings us to the end of this tutorial ! Until next time, readers.

References