Go GIN REST API Tutorial: Create Secure REST API using GO, GIN Framework, GORM, MYSQL

Go GIN REST API Tutorial: Create Secure REST API using GO, GIN Framework, GORM, MYSQL

Why to Build REST API with GO?

What’s GIN?

We will be creating a very simple REST API using

Prerequisites

Let’s Go!

Install Go

Install Go

How to Install Go?

go version

Create New Project

go mod init

Install Packages

go get github.com/go-sql-driver/mysql
go get github.com/gin-gonic/gin
go get github.com/jinzhu/gorm

Project Structure

Database Setup

//Config/Database.go package Configpackage Configimport (
"fmt"
"github.com/jinzhu/gorm"
)
var DB *gorm.DB// DBConfig represents db configuration
type DBConfig struct {
Host string
Port int
User string
DBName string
Password string
}
func BuildDBConfig() *DBConfig {
dbConfig := DBConfig{
Host: "localhost",
Port: 3306,
User: "root",
Password: "",
DBName: "book-store",
}
return &dbConfig
}
func DbURL(dbConfig *DBConfig) string {
return fmt.Sprintf(
"%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
dbConfig.User,
dbConfig.Password,
dbConfig.Host,
dbConfig.Port,
dbConfig.DBName,
)
}

Create Model

//Models/BookModel.gopackage Modelstype Book struct {
Id uint `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
Description string `json:"description"`
Price float64 `json:"price"`
Isbn string `json:"isbn"`
}
func (b *Book) TableName() string {
return "book"
}

Configure Routing

//Routes/Routes.gopackage Routespackage Routesimport (
"first-api/Controllers"
"github.com/gin-gonic/gin"
)
//SetupRouter ... Configure routes
func SetupRouter() *gin.Engine {
r := gin.Default()
grp1 := r.Group("/book-store")
{
grp1.GET("book", Controllers.GetBooks)
grp1.POST("book", Controllers.CreateBook)
grp1.GET("book/:id", Controllers.GetBookByID)
grp1.PUT("book/:id", Controllers.UpdateBook)
grp1.DELETE("book/:id", Controllers.DeleteBook)
}
return r
}

Create Controller

//Controllers/Book.go package Controllerspackage Controllersimport (
"first-api/Models"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
//GetBooks ... Get all books
func GetBooks(c *gin.Context) {
var book []Models.Book
err := Models.GetAllBooks(&book)
if err != nil {
c.AbortWithStatus(http.StatusNotFound)
} else {
c.JSON(http.StatusOK, book)
}
}
//CreateBook ... Create Book
func CreateBook(c *gin.Context) {
var book Models.Book
c.BindJSON(&book)
err := Models.CreateBook(&book)
if err != nil {
fmt.Println(err.Error())
c.AbortWithStatus(http.StatusNotFound)
} else {
c.JSON(http.StatusOK, book)
}
}
//GetBookByID ... Get the book by id
func GetBookByID(c *gin.Context) {
id := c.Params.ByName("id")
var book Models.Book
err := Models.GetBookByID(&book, id)
if err != nil {
c.AbortWithStatus(http.StatusNotFound)
} else {
c.JSON(http.StatusOK, book)
}
}
//UpdateBook ... Update the book information
func UpdateBook(c *gin.Context) {
var book Models.Book
id := c.Params.ByName("id")
err := Models.GetBookByID(&book, id)
if err != nil {
c.JSON(http.StatusNotFound, book)
}
c.BindJSON(&book)
err = Models.UpdateBook(&book, id)
if err != nil {
c.AbortWithStatus(http.StatusNotFound)
} else {
c.JSON(http.StatusOK, book)
}
}
//DeleteBook ... Delete the book
func DeleteBook(c *gin.Context) {
var book Models.Book
id := c.Params.ByName("id")
err := Models.DeleteBook(&book, id)
if err != nil {
c.AbortWithStatus(http.StatusNotFound)
} else {
c.JSON(http.StatusOK, gin.H{"id" + id: "is deleted"})
}
}

Handle Requests

//Models/Book.go package Modelspackage Modelsimport (
"first-api/Config"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
//GetAllBooks Fetch all book data
func GetAllBooks(book *[]Book) (err error) {
if err = Config.DB.Find(book).Error; err != nil {
return err
}
return nil
}
//CreateBook ... Insert New data
func CreateBook(book *Book) (err error) {
if err = Config.DB.Create(book).Error; err != nil {
return err
}
return nil
}
//GetBookByID ... Fetch only one book by Id
func GetBookByID(book *Book, id string) (err error) {
if err = Config.DB.Where("id = ?", id).First(book).Error; err != nil {
return err
}
return nil
}
//UpdateBook ... Update book
func UpdateBook(book *Book, id string) (err error) {
fmt.Println(book)
Config.DB.Save(book)
return nil
}
//DeleteBook ... Delete book
func DeleteBook(book *Book, id string) (err error) {
Config.DB.Where("id = ?", id).Delete(book)
return nil
}

Setting UP Server

//main.gopackage mainimport (
"first-api/Config"
"first-api/Models"
"first-api/Routes"
"fmt""github.com/jinzhu/gorm"
)var err error
func main() {
Config.DB, err = gorm.Open("mysql", Config.DbURL(Config.BuildDBConfig()))if err != nil {
fmt.Println("Status:", err)
}defer Config.DB.Close()
Config.DB.AutoMigrate(&Models.Book{})r := Routes.SetupRouter()
//running
r.Run()
}

Start Your Server

go run main.go
Go — GIN API

Endpoints

These are the endpoints we will use to create, update, read and delete the book data.

Create New Book

GIN — CREATE API

Get ALL Books

GIN-FETCH API

Get Book By ID

GIN-FETCH BY ID

Update The Book

GIN-UPDATE API

Delete The Book

GIN — DELETE API

Technology Enthusiast/ CTO/ Product Owner/ Connectivity Specialist/ API / Backend Development/ AI & ML, Prof: https://www.linkedin.com/in/travel-technology-cto/