GoLang Restful Api With Gin Gorm And Mysql | CRUD Operations | Latest

GoLang Restful Api With Gin Gorm And Mysql | CRUD Operations | Latest

    Here we will Gin framework for building our restful api. Gin is one of the best framework for GoLang. It also supports a lot of built in features like Authentication, Middleware, JSON Validation and Routing.

    Here we will build restful api for our flutter app, which we built before. Previously we built the restful api using pure GoLang. 

    But this time we will use GoLang framework Gin. If you want to combine this CRUD operations with flutter app, go ahead check it out. 

    If you are just looking for a restful api using Go and Gin, then just follow along from here.

    Project stucture

    Our project stucture would look like below.

    Go ahead create a folder name GG (you can name it anything you want).

    Installation of Gin

    First inside GG folder run the below command

    go mod init gin.com/gin

    With the above command, it will initialize GoLang for your project. Here gin.com/gin is just a name, you can name it anything.

    To install Gin in your project, run the below command from your GG folder.

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

    The above command will install Gin in your project directory. But before you do that,make sure you have Go install in your machine.

    The above command will generate go.sum and go.mod in your project folder.

     

    Database setup

    First we are going to set up the database. Make sure in your machine Mysql is install and at the same time you have phpmyadmin or mysql work bench installed. Inside it create a database name task_management and then create a table name tasks.

    Inside the GG folder create a folder name models and then create a file name db.go and put the below code

    package models
    
    import (
      "github.com/jinzhu/gorm"
      _ "github.com/jinzhu/gorm/dialects/mysql"
    )
    
    var DB *gorm.DB
    
    func ConnectDatabase() {
      database, err := gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/task_management")
    
      if err != nil {
        panic("Failed to connect to database!")
      }
    
      database.AutoMigrate(&Task{})
    
      DB = database
    }

    Use your on password for gorm.Open() function. Here we create a database connection and make a reference for it so that we can call it later.

    Later we will refer this database using DB.

    The above code will also create a database table name using database.AutoMigrate(&Task{})

    Task model

    In the table we will have four fields,

    id,

    task_name,

    task_detail

    date

    For these four fields we will create a model so that, we can interact with our table tasks.

    And inside this models folder create a file name table.go

    Code for model table table.go

    package models
    
    type Task struct {
      ID     uint   `json:"id" gorm:"primary_key"`
      TaskName  string `json:"task_name"`
      TaskDetail string `json:"task_detail"`
      Date string `json:"date"`
    }

     

    Creating controller

    Inside GG folder create another folder name controllers and inside this controllers folder create a file name task_controller.go

    First put the below code inside this task_controller.go

    package controllers
    
    import (
      "net/http"
    
      "github.com/gin-gonic/gin"
      "gin.com/gin/models"
    )
    type CreateTaskInput struct {
    	TaskName  string `json:"task_name" binding:"required"`
    	TaskDetail string `json:"task_detail" binding:"required"`
    
    }
    
    type UpdateTaskInput struct{
      TaskName  string `json:"task_name" binding:"required"`
    	TaskDetail string `json:"task_detail" binding:"required"`
    }

    Here we imported necessary modules and then we created struct for creating and updating task.We will need them for JSON data validation.

    Find All Tasks

    To find all tasks put the funcion in the task_controller.go file

    func FindTasks(c *gin.Context){
      var tasks []models.Task
      models.DB.Find(&tasks)
      c.JSON(http.StatusOk, g.H{"data":tasks})
    }

     

    Create Task

    func CreateTask(c *gin.Context) {
      // Validate input
      var input CreateTaskInput
      if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
      }
    
      // Create task
      task := models.Task{TaskName: input.TaskName, TaskDetail: input.TaskDetail, Date: "2020-03-10 00:00:00"}
      models.DB.Create(&task)
    
      c.JSON(http.StatusOK, gin.H{"data": task})
    
    }

     

    Find a Task

    func FindTask(c *gin.Context) {  // Get model if exist
      var task models.Task
      id := c.Request.URL.Query().Get("id")
      if err := models.DB.Where("id = ?", id).First(&task).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
        return
      }
    
      c.JSON(http.StatusOK, gin.H{"data": task})
    
    }

     

    Update a Task

    func UpdateTask(c *gin.Context) {
      // Get model if exist
      var task models.Task
      id := c.Request.URL.Query().Get("id")
      if err := models.DB.Where("id = ?", id).First(&task).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
        return
      }
    
      // Validate input
      var input UpdateTaskInput
      if err := c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
      }
    
      models.DB.Model(&task).Updates(input)
    
      c.JSON(http.StatusOK, gin.H{"data": task})
    }

     

    main.go

    package main
    
    import (
      "github.com/gin-gonic/gin"
      "gin.com/gin/models"
      "gin.com/gin/controllers"
    )
    
    func main() {
      r := gin.Default()
      models.ConnectDatabase()
    
      r.GET("/api/tasks", controllers.FindTasks)
      r.POST("/api/tasks", controllers.CreateTask)
      r.GET("/api/tasks/one", controllers.FindTask) 
      r.PUT("/api/tasks/update", controllers.UpdateTask) 
      r.Run()
    }