Production-ready Gin boilerplate with modular architecture, monorepo support, and Uber-fx powered automation.
- Modular Architecture: Domains like
iam,device, andnotificationfunction as independent modules. - Monorepo Structure: The
internaldirectory holds shared logic (Core), DTOs, and server configurations. - Dependency Injection: Powered by Uber-fx for clean lifestyle management and automatic component wiring.
- Automated Registration: Controllers and OpenAPI documentation are registered automatically.
- Authorization: Built-in Casbin support for RBAC/ABAC.
- Auto Swagger / OpenAPI: Reflection-based Swagger generation. No manual documentation required.
.
├── apps # Micro-apps / Domain Logic
│ ├── device
│ ├── iam # Identity & Access Management
│ │ ├── app # App Wiring (DB, Auth, Config, Module)
│ │ │ ├── casbin
│ │ │ ├── config
│ │ │ ├── database
│ │ │ └── Module.go
│ │ └── controller # HTTP Handlers
│ │ ├── v1
│ │ │ └── HelloController.go
│ │ └── Module.go # Fx registration logic
│ └── notification
├── cmd # Execution Entry Points
│ ├── iam/main.go
├── configs # App Configurations (YAML, Casbin)
├── internal # Shared Core Library
│ ├── base # Base interfaces (Controller, etc.)
│ ├── dto # Shared DTOs & Search/Metadata schemas
│ ├── logger # Zap-based logging
│ ├── server # Core HTTP server, Router & OpenAPI logic
│ └── utils # Shared utilities
├── go.mod
The boilerplate uses Uber-fx to handle dependency injection and lifecycle.
In apps/iam/controller/Module.go, controllers are annotated to a group:
fx.Annotate(
v1.NewHelloController,
fx.As(new(base.Controller)),
fx.ResultTags(`group:"controllers"`),
)The internal/server consumes this group to mount all routes automatically.
This project uses a code-first reflection approach via routerx.
In your Register method, use dto.OpenEndpoint to describe your API:
func (this *HelloController) Register(rg *routerx.Routerx) {
rg.POST(dto.OpenEndpoint{
Path: "/json",
Handler: this.JSON,
Summary: "Create something",
Request: &dto.CreatePostRequest{},
Responses: map[int]any{
200: gin.H{"status": "ok"},
},
})
}Ensure EnableOpenAPI: true is set in your controller's metadata:
Metadata: dto.Metadata{
Tag: "User Management",
EnableOpenAPI: true,
}Run your service and navigate to: http://localhost:8080/swagger/
The project uses Viper with environment variable expansion support.
Each app has its own configuration directory: configs/<app_name>/.
application.yaml: The main config file (parameterized with env vars).application.example.yaml: A template for required configurations.
You can define secrets and environment-specific values in your YAML using ${VAR_NAME} syntax:
database:
master:
password: ${DB_MASTER_PASSWORD}- Copy
application.example.yamltoapplication.yaml. - Set the required environment variables in your system or IDE.
git clone https://github.com/HoangHuy7/gin-boilerplate.git
cd gin-boilerplate
go mod downloadgo run cmd/gas/main.goCrafted with ❤️ by HoangHuy7
