Building a CRUD API with Go, Gin, MySQL and GORM
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:
-
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}'
-
Get All Books:
curl http://localhost:8080/books
-
Get a Single Book:
curl http://localhost:8080/books/1
-
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}'
-
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.