REST API's in Go

Creating simple REST end points in Go

Velu S Gautam1 min readLearnings

A simple, reliable REST endpoint in the open source language Go.

Install Go from https://golang.org/doc/install

Working Go REST API project: https://github.com/velusgautam/go-backend

First, create the project folder, e.g. go-backend.

main.go is the entry point. It has Go listen on a port (e.g. 2001) for requests and call the matching function based on the route path.

To get there, I used the folder structure below: routes for routing, models for the interfaces, and handlers for the request handlers.

main.go
handleRequest()

routes.GetRoutes()

/

/count

/users

handlers.Home

handlers.GetUserCount

handlers.GetUsers

The folder names are important in Go.

Functions with capital names become Public. Also, properties in a struct should be Capitalized, keep a note on that.

main.go

GO
package main

import (
	"fmt"
	"go-backend/routes"
	"log"
	"net/http"
)

// handleRequest will call respective routes in HandleFunc
func handleRequest() {
	for _, v := range routes.GetRoutes() {
		http.HandleFunc(v.Route, v.Handler)
	}
	fmt.Println("Serving from : http://localhost:2001")
	log.Fatal(http.ListenAndServe(":2001", nil))
}

func main() {
	handleRequest()
}
  • handleRequest

This loops through the routes and attaches the matching handler to each one, then listens on PORT:2001 via http.ListenAndServe.

routes/routes.go

GO
package routes

import (
	"go-backend/handlers"
	"go-backend/models"
)

type Route = models.Route

func GetRoutes() []Route {
	var routes []Route
	routes = append(routes, Route{Route: "/", Handler: handlers.Home})
	routes = append(routes, Route{Route: "/count", Handler: handlers.GetUserCount})
	routes = append(routes, Route{Route: "/users", Handler: handlers.GetUsers})
	return routes
}
  • Creates a routes slice with the type { Route: string, Handler: function } and attaches the matching route path and handler function to each entry.

models/model.go

GO
package models

import "net/http"

type User struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

type UserCount struct {
	Count int `json:"count"`
}

type Route struct {
	Route   string
	Handler func(http.ResponseWriter, *http.Request)
}
  • User: model struct holding Name and Email. The json tags define the keys used in the JSON output.

  • UserCount: holds the number of users.

  • Route: struct holding a single route.

handlers/home.go

GO
package handlers

import (
	"fmt"
	"net/http"
)

// Home handler give the default page
func Home(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Welcome to Go REST SERVICE")
}

A home handler that shows a welcome page.

handlers/users.go

GO
package handlers

import (
	"encoding/json"
	"go-backend/models"
	"net/http"
)

// User model from models
type User = models.User

// UserCount model from models
type UserCount = models.UserCount

var users []User

// GetUsers handler to fetch all users
func GetUsers(w http.ResponseWriter, r *http.Request) {
	users = append(users, User{Name: "John Doe", Email: "[email protected]"})
	users = append(users, User{Name: "Kim Jane", Email: "[email protected]"})
	users = append(users, User{Name: "Philip Mathew", Email: "[email protected]"})
	// setting content-type
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(users)
	return
}

// GetUserCount handler to fetch the users count
func GetUserCount(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	count := UserCount{Count: len(users)}
	json.NewEncoder(w).Encode(count)
	return
}
  • GetUsers

Public function that returns the list of users. Path: /users

  • GetUserCount

Public function that returns the user count. Path: /count

Run the Service 🏃🏽‍♂️

BASH
go run main.go

The service listens on http://localhost:2001

Comments