This project is a template for building web services using the Gin framework in Go. It provides a structured and scalable foundation for developing robust APIs.
- Modular Structure: Organized codebase for easy maintenance and scalability.
- RESTful API: Built-in support for creating RESTful endpoints.
- Database Integration: Pre-configured database layer for efficient data management.
- Caching: Integrated caching mechanism for improved performance.
- Error Handling: Standardized error handling and reporting.
- Middleware Support: Easy integration of custom middleware.
- Logging: Built-in logging for better debugging and monitoring.
- Graceful Shutdown: Ensures proper closure of resources and connections.
- Docker Support: Containerization ready for easy deployment.
- Tracing and Metrics: Integrated for better observability.
The application is configured using a YAML file located next to main.go
. Edit it to set your specific configuration:
server: port: 8080 timeout: 10s
uptrace: dsn: http://project2_secret_token@localhost:14317/2 enable_open_telemetry: true
database: host: localhost port: 5432 user: youruser password: yourpassword dbname: yourdbname driver: postgres maxOpenConns: 5 maxIdleConns: 2 connMaxLifetime: 30m
redis: host: localhost port: 6379 password: "" db: 0
log: level: info format: json
Adjust the values according to your environment and requirements. The maxOpenConns
, maxIdleConns
, and connMaxLifetime
settings control database connection pooling.
You can override any configuration value with an environment variable by
replacing dots in the key with underscores and uppercasing it. For example,
REDIS_HOST=cache.example.com
overrides redis.host
. This is useful when
deploying to containerized or cloud environments where settings are provided via
environment variables.
- Album Management: CRUD operations for managing albums.
- Error Handling: Centralized error handling with custom error types.
- Caching: Request caching to improve response times.
- Database Integration: Configured database layer with connection pooling.
- Middleware: Custom middleware for various purposes like error handling.
- Logging: Structured logging for better traceability.
- Graceful Shutdown: Proper shutdown procedure to ensure all resources are released.
- Docker Support: Dockerized application for easy deployment and scaling.
- Tracing and Metrics: Integrated tracing and metrics for monitoring and performance analysis.
- Clone the repository
- Create a configuration file as shown in docs/basic_server_setup.md
- Run
go mod tidy
to install dependencies - Run
go run main.go
to start the server
To start the server, follow these steps:
-
Ensure you have Go installed on your system.
-
Open a terminal and navigate to the project root directory.
-
Run the following command:
go run main.go
-
You should see output similar to this:
2023/06/10 15:30:45 Starting server on :8080
-
The server is now running and listening on port 8080 (or the port specified in your
config.yaml
).
You can now send requests to http://localhost:8080
to interact with the API.
To stop the server, press Ctrl+C
in the terminal. The application will perform a graceful shutdown, ensuring all resources are properly released.
For more detailed information on each component, please refer to the respective files in the project structure.
Swagger documentation is generated with swag and served at /docs/index.html
when the server is running.
To update the documentation:
- Install the
swag
CLI:go install github.com/swaggo/swag/cmd/swag@latest
. - Run
swag init -g main.go
from the repository root. - Start the server and browse to
http://localhost:8080/docs/index.html
.
Each handler and middleware includes Swagger comments so new routes should follow the existing pattern. Middleware attached to a route is documented using the @Middleware
annotation.
Middleware can be registered globally, for route groups, or for individual routes. Global middleware is added in app/server.go
, group middleware in each module's init.go
, and route middleware when declaring the handler.
When implementing new middleware, document it with a comment starting with // @Middleware
so Swagger includes the description.
Client projects can extend the request pipeline by registering their own middleware before starting the server. Middleware functions must follow the Gin handler signature:
func(c *gin.Context)
Use UseBefore
, UseAfter
, and UseFinal
to extend the middleware stack. All
middleware must be registered before calling RegisterRoutes
so it can be
applied in the correct order. The execution sequence is:
UseBefore
middleware- built-in middleware (recovery, tracing, logging, etc.)
UseAfter
middleware- route handlers
UseFinal
middleware
UseFinal
handlers should always call c.Next()
so the request reaches the
actual route handler before running their cleanup logic:
srv := server.New(cfg)
srv.UseBefore(func(c *gin.Context) {
log.Println("before built-in")
c.Next()
})
srv.UseAfter(func(c *gin.Context) {
log.Println("before routes")
c.Next()
})
srv.UseFinal(func(c *gin.Context) {
c.Next()
log.Println("after route")
})
srv.RegisterRoutes(registerRoutes)
srv.Run()
Core middleware for tracing, context propagation, error handling and logging always runs first and cannot be replaced. Custom middleware executes next, followed by any route‑specific middleware configured within modules.
For specialized scenarios you may want to bootstrap the HTTP server yourself. Use
ApplyMiddleware()
to attach all middleware, retrieve the router with Router()
,
and manage shutdown using GracefulShutdown
:
srv.ApplyMiddleware()
s := &http.Server{Handler: srv.Router()}
go s.ListenAndServe()
// trigger shutdown somehow
server.GracefulShutdown(s, time.Second*5)
The HTTP server exposes composable building blocks so you can run additional protocols alongside Gin. For example, start a gRPC or GraphQL server in the same process and manage their lifecycles together:
go srv.Run() // existing HTTP service
grpcSrv := grpc.NewServer()
go grpcSrv.Serve(lis)
// shutdown logic
server.GracefulShutdown(httpSrv, time.Second*5)
grpcSrv.GracefulStop()
The template keeps middleware, configuration and shutdown utilities decoupled, making it straightforward to integrate other protocols without altering the core modules.
├── app // Core application modules
│ ├── apiErrors // API error helpers
│ ├── cache // request caching layer
│ ├── db // database connectors
│ ├── middleware // shared middleware
│ └── server.go // server bootstrap
├── example
│ ├── config // application configuration
│ │ └── config.yaml
│ ├── features
│ │ └── albums // Albums domain implementation
│ ├── seed // seed data
│ └── main.go
├── go.mod
└── go.sum // Go module checksum file
- Add swagger
- add versioning
- Add tests
- logger
- graceful shutdown
- create a docker image
- add tracing and metrics
- CI/CD