MarkazSoft

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

MarkazSoft
Building a REST API with Go and Gin: Step-by-Step
July 31, 2025 · by MarkazSoft Team

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.

Back to top