Building a REST API with Go and Gin: Step-by-Step

Building a REST API with Go and Gin: Step-by-Step
Learn how to create a high-performance RESTful API using Go and the Gin framework, complete with routing, middleware, and testing.
Prerequisites
- Go installed (v1.20+). Check with
go version
. - Basic familiarity with Go modules and packages.
- Git installed for version control.
- Optional: Docker for containerization.
Project Setup
Initialize a new Go module and install Gin:
mkdir gin-api
cd gin-api
go mod init github.com/yourusername/gin-api
go get github.com/gin-gonic/gin
Create a basic main.go
:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "pong"})
})
r.Run(":8080")
}
Run with go run main.go
and visit http://localhost:8080/ping.
Models & DTOs
Create a models/book.go
to define your resource:
package models
type Book struct {
ID uint 'json: "id" gorm: "primaryKey"'
Title string 'json: "title"'
Author string 'json: "author"'
}
And a DTO for creation requests in dto/create_book.go
:
package dto
type CreateBookInput struct {
Title string 'json: "title" binding: "required"'
Author string 'json: "author" binding: "required"'
}
Defining Routes & Handlers
In main.go
, set up CRUD endpoints:
import (
"github.com/gin-gonic/gin"
"github.com/yourusername/gin-api/controllers"
)
func main() {
r := gin.Default()
api := r.Group("/api")
{
api.GET("/books", controllers.GetBooks)
api.POST("/books", controllers.CreateBook)
api.GET("/books/:id", controllers.GetBook)
api.PUT("/books/:id", controllers.UpdateBook)
api.DELETE("/books/:id", controllers.DeleteBook)
}
r.Run()
}
Example handler in controllers/book.go
:
package controllers
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/yourusername/gin-api/models"
"gorm.io/gorm"
)
// assuming db is initialized...
func GetBooks(c *gin.Context) {
var books []models.Book
models.DB.Find(&books)
c.JSON(http.StatusOK, gin.H{"data": books})
}
Adding Middleware
Enable CORS and logging:
import "github.com/gin-contrib/cors"
r := gin.Default()
r.Use(cors.Default())
r.Use(gin.Logger(), gin.Recovery())
This ensures cross-origin requests and automatic request logging.
Testing Endpoints
Use curl
or a tool like Postman:
# Create
curl -X POST http://localhost:8080/api/books -H "Content-Type: application/json" -d '{"title":"1984","author":"George Orwell"}'
# List
curl http://localhost:8080/api/books
Alternatively write Go tests with httptest
for automated CI.
Dockerizing the API
Create a Dockerfile
:
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o gin-api .
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/gin-api .
EXPOSE 8080
CMD ["./gin-api"]
Build & run:
docker build -t gin-api .
docker run -p 8080:8080 gin-api
Conclusion
You now have a fully functional REST API in Go with Gin: organized models, routes, middleware, and Docker support. From here, consider adding authentication, pagination, and advanced error handling to take your API production-ready.