Building a CRUD API with Go, Gin, MySQL and GORM

3 min read .

In this tutorial, we will create a simple CRUD (Create, Read, Update, Delete) API using Go with the Gin web framework, MySQL for database management, and GORM as the ORM (Object-Relational Mapping) library. Additionally, we will use the godotenv package to manage environment variables securely.

Step 1: Setting Up the Project

First, create a new directory for your project and initialize a Go module:

mkdir myapp
cd myapp
go mod init myapp

Step 2: Install Dependencies

Next, install the necessary packages: Gin for handling HTTP requests, GORM for interacting with the MySQL database, the MySQL driver for GORM, and godotenv for loading environment variables from a .env file.

go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u github.com/joho/godotenv

Step 3: Create the MySQL Database

Log in to your MySQL server and create a new database for your application:

CREATE DATABASE myapp;

Step 4: Set Up Environment Variables

Create a .env file in the root of your project to store your database credentials:

nano .env

Add the following content to the .env file:

DB_USER=root
DB_PASSWORD=yourpassword
DB_NAME=myapp
DB_HOST=127.0.0.1
DB_PORT=3306

This .env file allows you to manage your database connection details securely and keep them out of your source code.

Step 5: Writing the Application Code

Create a file named app.go in your project directory and add the following code:

package main

import (
	"log"
	"os"

	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/joho/godotenv"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

type Book struct {
	gorm.Model
	Title  string  `json:"title"`
	Author string  `json:"author"`
	Price  float64 `json:"price"`
}

func init() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}

	dsn := os.Getenv("DB_USER") + ":" + os.Getenv("DB_PASSWORD") + "@tcp(" + os.Getenv("DB_HOST") + ":" + os.Getenv("DB_PORT") + ")/" + os.Getenv("DB_NAME") + "?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}

	db.AutoMigrate(&Book{})

	DB = db
}

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

	r.POST("/books", CreateBook)
	r.GET("/books", GetBooks)
	r.GET("/books/:id", GetBook)
	r.PUT("/books/:id", UpdateBook)
	r.DELETE("/books/:id", DeleteBook)

	r.Run(":8080")
}

func CreateBook(c *gin.Context) {
	var book Book

	if err := c.ShouldBindJSON(&book); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	DB.Create(&book)

	c.JSON(http.StatusOK, book)
}

func GetBooks(c *gin.Context) {
	var books []Book

	DB.Find(&books)

	c.JSON(http.StatusOK, books)
}

func GetBook(c *gin.Context) {
	id := c.Param("id")

	var book Book

	if err := DB.First(&book, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
		return
	}

	c.JSON(http.StatusOK, book)
}

func UpdateBook(c *gin.Context) {
	id := c.Param("id")

	var book Book

	if err := DB.First(&book, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
		return
	}

	if err := c.ShouldBindJSON(&book); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	DB.Save(&book)

	c.JSON(http.StatusOK, book)
}

func DeleteBook(c *gin.Context) {
	id := c.Param("id")

	var book Book

	if err := DB.First(&book, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
		return
	}

	DB.Delete(&book)

	c.JSON(http.StatusOK, gin.H{"message": "Book deleted"})
}

Step 6: Running the Application

To start your application, use the following command:

go run app.go

The server will start on localhost:8080.

Step 7: Testing the API Endpoints

You can test the API endpoints using curl or Postman. Here are some examples:

  1. Create a Book:

    curl -X POST http://localhost:8080/books -H "Content-Type: application/json" -d '{"title": "Go Programming", "author": "John Doe", "price": 29.99}'
  2. Get All Books:

    curl http://localhost:8080/books
  3. Get a Single Book:

    curl http://localhost:8080/books/1
  4. Update a Book:

    curl -X PUT http://localhost:8080/books/1 -H "Content-Type: application/json" -d '{"title": "Advanced Go", "author": "Jane Doe", "price": 39.99}'
  5. Delete a Book:

    curl -X DELETE http://localhost:8080/books/1

Conclusion

In this tutorial, we’ve built a basic CRUD API using Go, Gin, MySQL, and GORM, and managed our environment variables with godotenv. This setup provides a robust foundation for developing more complex applications. By using Gin, GORM, and MySQL, you can efficiently manage HTTP requests and database interactions, making your Go applications powerful and easy to maintain.

Tags:
Golang

See Also

chevron-up