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.
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 fileThis 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/ginImplement 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
