Creating Api Using Httprouter In Golang

We will create a rest api using httprouter in golang#

httprouter is api router library built on top of golang’s net/http package. It gives some extra functionality like mapping routes based on api method like GET,POST,PUT,DELETE etc.

There are lots of full featured library is available for golang to make an robust api but httprouter is lightwieght which do not hide lots of functionality and gives a room to tweak based on usecase.

so our directory structure will look like this -

- main.go
- public
- routes
    - api.go
    - main.go
- controllers
    - controller.go
    - home_controller.go

first add httprouter dependency to our project

go get github.com/julienschmidt/httprouter

initialize your project using go mod init command like below in the root directory.

go mod init example.com/http-api

Create routes/main.go

package routes

import (	
	"net/http"
	"github.com/julienschmidt/httprouter"
)

type Routes struct {
	router *httprouter.Router	
}

func New() *Routes {

	routes := &Routes{router: httprouter.New()}
	// Serving static content on root url from public folder
	routes.router.ServeFiles("/public/*filepath", http.Dir("./public"))
	routes.ApiRoutes()
	return routes
}

func (r *Routes) GetHttpRouter() *httprouter.Router {
	return r.router
}

as you can see i have mounted public/ folder for static content so that if you have static index.html file that can be served directly using localhost:8001/public/index.html

now lets create our api file which will hold all of our routes.

routes/api.go

package routes

import (
	"example.com/http-api/controllers"
)

func (r *Routes) ApiRoutes() {
	router := r.router
	
	userController := controllers.UserController{}	

	//User Routes
	router.GET("/users", userController.GetAllUsers)
	router.GET("/users/:id", userController.GetUser)
    router.POST("/users",userController.AddUser)
    router.PUT("/users",userController.UpdateUser)

}


we are done with our routing, now add controller files which will handle routes.

in controllers folder add controller.go file, it will hold some helper function which is required by all of our controllers.

controllers/controller.go

package controllers

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

func SendJson(w http.ResponseWriter, status int, data interface{}) {
	jsonString, err := json.Marshal(data)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(err.Error()))
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	w.Write(jsonString)
}

Now lets create our first user_controller.go file inside controllers directory. this file will hold our business logic.

controllers/user_controller.go


package controllers

import (
	"fmt"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

type UserController struct {
}

func (s *UserController) GetAllUsers(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	users  := []struct{
        ID string `json:"id"`
        Firstname string `json:"first_name"`
        Lastname string `json:"last_name"`
    }{
        {
            ID : "435564bggfh345"
            Firstname: "john"
            Lastname: "Doe"
        },
        {
            ID : "435564bggfh345"
            Firstname: "john"
            Lastname: "Doe"
        }
    }
	
	SendJson(w, http.StatusOK, users)

}

func (s *UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	var id = p.ByName("id")
	fmt.Println(id)
	user  := struct{
        ID string `json:"id"`
        Firstname string `json:"first_name"`
        Lastname string `json:"last_name"`
    }{
       
            ID : "435564bggfh345"
            Firstname: "john"
            Lastname: "Doe"
       
    }
	SendJson(w, http.StatusOK, user)

}
func (s *UserController) AddUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
    SendJson(w, http.StatusOK, map[string]interface{}{"msg":"Users added successfully"})
}
func (s *UserController) UpdateUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
    SendJson(w, http.StatusOK, map[string]interface{}{"msg":"Users updated successfully"})

}


As you can see i have only given you the structure of controller. you can implement your own logic for fetching data from database like mysql or mongodb.

Now its time to start our api server in main.go file. we will initialize our routings in main function. content of main.go will look like below.

main.go


package main

import (
	"fmt"
	
	"example.com/http-api/routes"
	"net/http"

	
)

func main() {

    router := routes.New()

	httpRouter := router.GetHttpRouter()

	fmt.Println("Lisitening on port : 8001")
	err = http.ListenAndServe(":8001", httpRouter)
	if err != nil {
		fmt.Println("Unable to start server", err)
	}

}

If you will run main.go file it will start the server on port localhost:8001

now use your postman to hit the api and get the response. I hope this is enough for you to get started with httprouter package for building api in go.

Thanks you

comments powered by Disqus