Build a Complete Golang REST API: From Setup to Deployment

This step‑by‑step guide walks you through installing Go, configuring the environment, structuring a project, using Gin to create CRUD endpoints, adding middleware, managing configuration, testing, generating Swagger docs, optimizing performance, and deploying the service with Docker or systemd.

Golang Shines
Golang Shines
Golang Shines
Build a Complete Golang REST API: From Setup to Deployment

Overview

The tutorial demonstrates how to build a full‑featured REST API service with Go, emphasizing practical hands‑on work rather than theory. It highlights Go's fast compilation, low memory footprint, strong concurrency via goroutines, and simple deployment as a single binary.

Environment Setup

Install the latest stable Go (1.21 at the time of writing) and verify with go version. Configure essential environment variables ( GOPATH, GOROOT, GOBIN) and enable Go Modules for version‑agnostic dependency management.

Project Structure

project/
├── cmd/
│   └── api/
│       └── main.go   # program entry
├── internal/
│   ├── handlers/      # HTTP handlers
│   ├── models/        # data models
│   ├── services/      # business logic
│   ├── repositories/  # data access layer
│   └── middleware/    # custom middleware
├── pkg/
│   ├── config/        # configuration management
│   └── database/      # DB connection
├── api/
│   └── swagger.yaml   # API documentation
├── scripts/           # deployment scripts
├── tests/             # test files
└── go.mod             # dependency file

This layered layout keeps responsibilities clear and improves testability.

Building the API with Gin

Create the project directory, initialize a module, and install Gin:

mkdir my-rest-api
cd my-rest-api
go mod init github.com/yourname/my-rest-api
go get -u github.com/gin-gonic/gin

Implement a basic server in cmd/api/main.go that registers a health‑check endpoint and starts on port 8080. Use gin.Default() to obtain a router with logging and recovery middleware.

Database Integration with GORM

Install GORM and the MySQL driver, define a User model with fields and tags, and create a database initialization function that opens the connection, runs AutoMigrate, and logs success or failure.

type User struct {
    ID        uint   `gorm:"primarykey" json:"id"`
    Name      string `gorm:"size:100;not null" json:"name"`
    Email     string `gorm:"size:255;uniqueIndex;not null" json:"email"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
    DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}

func (User) TableName() string { return "users" }

CRUD Handlers

Implement CreateUser, GetUser, ListUsers, UpdateUser, and DeleteUser in internal/handlers/user.go. Each handler validates input, interacts with the global DB instance, and returns JSON responses with appropriate HTTP status codes.

Routing

func setupRouter() *gin.Engine {
    r := gin.Default()
    r.Use(gin.Logger())
    r.Use(gin.Recovery())
    api := r.Group("/api/v1")
    {
        userHandler := &handlers.UserHandler{}
        users := api.Group("/users")
        {
            users.POST("", userHandler.CreateUser)
            users.GET("", userHandler.ListUsers)
            users.GET("/:id", userHandler.GetUser)
            users.PUT("/:id", userHandler.UpdateUser)
            users.DELETE("/:id", userHandler.DeleteUser)
        }
    }
    return r
}

Middleware

Provide a JWT authentication middleware that extracts the Authorization header, validates the token with github.com/golang-jwt/jwt/v4, stores the user ID in the context, and aborts on failure. Also add a logging middleware that records request method, path, client IP, status, and latency.

Configuration Management

Use Viper to load a config.yaml file (or environment variables) into a typed Config struct covering server, database, and JWT settings.

type Config struct {
    Server   ServerConfig   `mapstructure:"server"`
    Database DatabaseConfig `mapstructure:"database"`
    JWT      JWTConfig      `mapstructure:"jwt"`
}

Testing

Write unit tests for handlers using Gin's test mode and httptest. Example: TestCreateUser sends a POST request with JSON payload and asserts a 201 Created response and success message. Use an in‑memory SQLite database for isolated handler tests.

Swagger Documentation

Install swaggo/swag, annotate handler functions with Swagger comments ( @Summary, @Description, etc.), and generate docs folder via swag init -g cmd/api/main.go. The generated JSON/YAML can be served with Gin.

Performance Optimizations

Configure GORM's underlying SQL DB connection pool ( SetMaxIdleConns(10), SetMaxOpenConns(100), SetConnMaxLifetime(time.Hour)).

Introduce Redis caching for frequently read data, with helper functions SetCache and GetCache that marshal values to JSON.

Deployment Options

Compile a static Linux binary ( GOOS=linux GOARCH=amd64 go build -o my-api cmd/api/main.go) and copy it to a server, or build a multi‑stage Docker image that compiles in a golang:1.21-alpine builder and runs the binary on a minimal alpine base. Also provide a systemd service unit file for managing the process.

Monitoring and Health Checks

Implement a health‑check endpoint that verifies database connectivity and returns JSON status. Use structured logging libraries such as Zap for consistent log output.

Troubleshooting

Common issues include database connection failures (check service status, DSN format, network), port conflicts (use lsof to find the occupying process), and memory leaks (enable net/http/pprof and analyze heap profiles).

Conclusion

Following the tutorial equips you with the core skills to develop, test, document, optimize, and deploy a production‑ready Go REST API service.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockertestingMiddlewaregoREST APIGORMGin
Golang Shines
Written by

Golang Shines

We share daily the latest Golang technical articles, practical resources, language news, tutorials, and real-world projects to help everyone learn and improve.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.