Working with GORM ORM with Go and Gin Server

GORM is a popular ORM used with golang to communicate with SQL database. In this article, we will look at how we can setup GORM in our go server using gin framework.

Create New Go App

Lets start by creating a new go app.

mkdir <go-app>
cd <go-app>
go mod init <mod-name>

Install Dependencies

For this project, we will need dependencies like gin, gorm, sqlite. Let us install them with the following command.

go get -u github.com/gin-gonic/gin 
go get -u gorm.io/gorm 
go get -u gorm.io/driver/sqlite

Initialize DB

Lets initialise the database using sqlite. This will create a single db file which will store all the records inside it.

// db/index.go
package db
import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

var DB *gorm.DB
var err error
func Init() {
    DB, err = gorm.Open(sqlite.Open("api.db"), &gorm.Config{})
    if err != nil {
        panic("Could not connect to database")
    }
}

Create main file

Now let us import the DB instance inside our main function and initialize the sqlite database.

// main.go
package main

import (
    "go_sample_app/db"
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {

    // Initialize DB 
    db.Init()
    server := gin.Default()
    server.GET("/", func(ctx *gin.Context) {
        ctx.JSON(http.StatusOK, gin.H{
            "message": "Server Started",
        })
    })
    server.Run(":8080")

}

Create Products Model

Let us create products model using go structs and create some functions like Fetch and Save to perform operations on the products model

//product.go 
type Product struct {
    gorm.Model
    Name  string `json:"name" binding:"required"`
    Price int    `json:"price" binding:"required"`
}
func (p *Product) Save() (*Product, error) {

    result := db.DB.Save(&p)
    if result.Error != nil {
        return nil, result.Error
    }

    return p, nil

}

Migrate the Products Model

Lets migrate the products model inside the main file. Using the following lines of code.

    db.DB.AutoMigrate(&models.Product{})

Start your Go Server

For this example, let us run the go server without any hot-reloading.

go run .

Output

Check your application console to see if you get any errors.

Create routes and controller functions to perform operations on the database

In this task, create routes folder and routes.go file which will contain the routes required to perform GET and POST operations on the products model. Import the controller functions that we created in the previous step and attach them to the routes.

func AddProducts(ctx *gin.Context) {

    var p models.Product
    err := ctx.ShouldBindJSON(&p)
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": "Something went Wrong",
            "error":   err.Error(),
        })
        return
    }

    result, err := p.Save()
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": "Error",
            "error":   err.Error(),
        })
        return
    }

    ctx.JSON(http.StatusOK, gin.H{
        "message": "Success",
        "data":    result,
    })

}
package routes
import (
    "go_sample_app/controllers"
    "github.com/gin-gonic/gin"
)

func RegisterRoutes(server *gin.Engine) {
    server.GET("/products", controllers.GetProducts)
    server.POST("/products/add", controllers.AddProducts)
}

Test the Endpoints

Now it is time to test the endpoints which were created in the previous steps.

The above image clearly shows that we get a status 200 code when we test the endpoint. Thus we can conclude that our functionality is working successfully.

Conclusion

We have successfully integrated GORM ORM with go server and established a connection to sqlite database.

1
Subscribe to my newsletter

Read articles from Mithilesh Tarkar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mithilesh Tarkar
Mithilesh Tarkar