logo
Published on

GoLang - Introduction | Create REST API with Auto Reload

featured Image
Authors

GoLang - Introduction | Create REST API with Auto Reload

Go is a High-Level, Strong ( you can not change variables type ) and Statically (All variables should be declared at compile time ) typed, complied programing language created by Google.

Key Features

  • Simplicity - Go have only very useful and necessary features.
  • Fast Compile - Go have very little compile time.
  • Garbage Collection - Garbage collection is a type of memory management that is automated.
  • Built-In-Concurrency - The capacity for functions to operate independently of one another.
  • Compiled into standalone binaries

Table of content-

Gin - Web Development Framework

Gin allows you to create Go web apps and microservices. It includes a set of frequently used capabilities (e.g., routing, middleware support, rendering, etc.)

In this article, I am going to create a simple GO server using Gin that will allow you to perform CRUD (Create, Read, Update, Delete) operations. I will also implement auto-reload so you do not need to restart the server again and again after making some changes.

Create a server using Gin

Steps are included in this process-

  1. Create a GO project.
  2. Install and import Gin in the project.
  3. Add AIR config for auto-reload.
  4. Add get, post, put, and update APIs.
  5. Validate responses using postman.

So, we are going to start with the very first step-

Create a GO project

First, we need to initialize GO in the project.

go mod init gin-example-project

It will create a go.mod file in the root folder of ours project.

Now, we can create main.go file to start writing code.

To test everything working, paste hello word program in main.go file and run it.

package main
import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

To run this code, simply command-

go run main.go

// expected output: Hello, World!

Install and Import Gin in Project

To install Gin, Go v1.13+ is required. To install gin, run-

go get -u github.com/gin-gonic/gin

After installing, you can import gin in your main.go file.

import "github.com/gin-gonic/gin"

We also need net/http to send status.

import "net/http"

Add AIR config for auto reload

Create a .air.conf file in the root folder of the project and add this config in that file.

import _ "github.com/joho/godotenv/autoload"
root = "."
tmp_dir = "tmp"

[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o ./tmp/main ."
# Binary file yields from `cmd`.
bin = "tmp/main"
# Customize binary.
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop to run old binary when build errors occur.
stop_on_error = true
# This log file places in your tmp_dir.
log = "air_errors.log"

[log]
# Show log time
time = false

[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# Delete tmp directory on exit
clean_on_exit = true

Now, you have to run your project using AIR. So you need to command-

air run main.go

Add GET, POST, PUT, and UPDATE APIs

I have added some sample data for this. You can copy it from here https://github.com/gyanendraknojiya/GO-Gin-REST-API#get-all-users

Create a main function in main.go file, and run your server a port 8080 (Port can be any).

func main(){
	router  :=  gin.Default()
	router.Run("localhost:8080")
}

Now you can see the server running. We need to create user json.

type user struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	UserName string `json:"userName"`
	Email    string `json:"email"`
	Phone    string `json:"phone"`
	Website  string `json:"website"`
}
var users = []user{
	{
		ID:       "1",
		Name:     "Leanne Graham",
		UserName: "Bret",
		Email:    "Sincere@april.biz",
		Phone:    "1-770-736-8031 x56442",
		Website:  "hildegard.org",
	},
	{
		ID:       "2",
		Name:     "Ervin Howell",
		UserName: "Antonette",
		Email:    "Shanna@melissa.tv",
		Phone:    "010-692-6593 x09125",
		Website:  "anastasia.net",
	},
}

Add all APIs in main function-

func main() {
	router := gin.Default()

	router.GET("/", getAllUsers)
	router.GET("/user/:id", getUserById)
	router.POST("/addUser", addUser)
	router.PUT("/updateUser", updateUser)
	router.DELETE("/deleteUser", deleteUser)

	router.Run("localhost:8080")
}

getAllUsers will have-

func getAllUsers(c *gin.Context) {
	c.IndentedJSON(http.StatusOK, users)
}

getUserById

func getUserById(c *gin.Context) {
	ID := c.Param("id")
	for _, i := range users {
		if i.ID == ID {
			c.IndentedJSON(http.StatusOK, i)
			return
		}
	}
	c.IndentedJSON(http.StatusNotFound, gin.H{"message": "user not found!"})
}

addUser

func addUser(c *gin.Context) {
	var newUser user

	if err := c.BindJSON(&newUser); err != nil {
		fmt.Println(err)
		return
	}

	users = append(users, newUser)
	c.IndentedJSON(http.StatusOK, users)
}

updateUser

func updateUser(c *gin.Context) {
	var updateUser user

	if err := c.BindJSON(&updateUser); err != nil {
		fmt.Println(err)
		return
	}
	if updateUser.ID == "" {
		c.IndentedJSON(400, gin.H{"message": "id is missing!"})
		return
	}

	for i, user := range users {
		if user.ID == updateUser.ID {

			if updateUser.Name != "" {
				user.Name = updateUser.Name
			}
			if updateUser.Email != "" {
				user.Email = updateUser.Email
			}
			if updateUser.Phone != "" {
				user.Phone = updateUser.Phone
			}
			if updateUser.Website != "" {
				user.Website = updateUser.Website
			}
			users[i] = user
			c.IndentedJSON(http.StatusOK, users)
			return
		}
	}
	c.IndentedJSON(400, gin.H{"message": "id is not found!"})
}

deleteUser

func RemoveIndex(s []user, index int) []user {
	return append(s[:index], s[index+1:]...)
}

func deleteUser(c *gin.Context) {
	var deleteUser user

	if err := c.BindJSON(&deleteUser); err != nil {
		fmt.Println(err)
		return
	}
	if deleteUser.ID == "" {
		c.IndentedJSON(400, gin.H{"message": "id is missing!"})
		return
	}

	for i, user := range users {
		if user.ID == deleteUser.ID {
			users = RemoveIndex(users, i)
			c.IndentedJSON(http.StatusOK, users)
			return
		}
	}
	c.IndentedJSON(400, gin.H{"message": "id is not found!"})
}

That's all. We can now utilize these APIs to get, add, update, and remove data from the server.

Get source code: https://github.com/gyanendraknojiya/GO-Gin-REST-API