A comprehensive boilerplate for building scalable Golang-based REST API services with microservice architecture, API gateway, and PostgreSQL support.
- Microservice Architecture: API Gateway with service discovery
- Distributed Tracing: OpenTelemetry with Jaeger for observability across services
- PostgreSQL Integration: Connection pooling and migrations
- Advanced Logging System: Structured JSON logging with file rotation and Docker integration
- Configuration Management: Environment-based config with Viper
- Docker Support: Containerized deployment with docker-compose
- REST API Framework: Gin-based HTTP server with middleware
- Service Instantiation: Automated script to create new services
- Makefile Workflow: Complete build, test, and deployment automation
Recent improvements to the Makefile for better maintainability and dynamic service support:
- Variables are now loaded from
.envfiles into Make using a dynamic macro. - Eliminates duplication between Makefile and
.envfiles. SERVICE_NAMEis excluded from loading to prevent command-line overrides.
SERVICES: Auto-detects all services inservices/directory (must end with-service).SERVICES_WITH_MIGRATIONS: Detects services withmigrations/anddependencies.json.- Supports automatic integration of new services without manual Makefile updates.
- Restored dependency resolution for proper migration ordering.
- Fixed service name passing to prevent truncation issues.
- Enhanced error handling for failed migrations.
- Easier maintenance and extension.
- Seamless support for
create-service.shgenerated services. - Proper dependency management across services.
To ensure services are automatically detected and integrated:
- Suffix Required: All services must end with
-service(e.g.,user-service,auth-service). - Directory Structure: Services live in
services/{service-name}/. - Migration-Enabled: For migrations, include
migrations/withdependencies.jsonandenvironments.json.
services/
βββ user-service/ # β
Detected
β βββ migrations/ # β
Migration-enabled
β βββ ...
βββ auth-service/ # β
Detected
βββ payment_svc/ # β Not detected (wrong suffix)
- Enables dynamic Makefile operations without manual edits.
- Ensures
create-service.shcreates compatible services. - Maintains consistency across the project.
- Service URL Configuration: Environment-based service discovery and communication
- Middleware Architecture: Authentication, logging, tracing, and request processing patterns
- Security Architecture: Authentication, authorization, and service exposure guidelines
- Logging System: Comprehensive guide to logging configuration, options, and troubleshooting
- Distributed Tracing: Complete OpenTelemetry implementation with Jaeger
- Overview & Architecture
- Developer Guide
- Configuration
- Database Tracing: Instrumenting database operations for performance monitoring
- Monitoring & Troubleshooting
- Best Practices
- Service Creation Guide: How to create new services using the boilerplate
- Service Naming Conventions: Required naming and structure for automatic integration
- Air Hot Reload: Development setup with live reloading
- Migrations: Database migration management and best practices
- CLI Utilities: Command-line tools for development and operations
- RBAC API Guide: Complete Role-Based Access Control system documentation with API endpoints, implementation details, and testing
- Authentication API Examples: Complete API usage examples with authentication
- Distributed Tracing Implementation Plan: Detailed roadmap for implementing OpenTelemetry tracing across microservices
- Future Development Plan: Roadmap of planned features and enhancements
- CLI Utility Plan: Planned CLI enhancements and features
- Changelog: Version history and change notes
service-boilerplate/
βββ api-gateway/ # Central API gateway service
β βββ cmd/
β βββ internal/
β β βββ config/
β β βββ handlers/
β β βββ middleware/
β β βββ services/
β βββ config.yaml
βββ services/ # Individual microservices
β βββ user-service/ # Example user management service
β βββ cmd/
β βββ internal/
β β βββ config/
β β βββ database/
β β βββ handlers/
β β βββ models/
β β βββ repository/
β β βββ services/
β βββ migrations/
β βββ config.yaml
βββ common/ # Shared libraries
β βββ logging/
β βββ database/
β βββ config/
βββ docker/ # Docker configurations
β βββ docker-compose.yml
βββ scripts/ # Utility scripts
β βββ create-service.sh
βββ templates/ # Service templates
βββ Makefile # Build automation
The service-boilerplate implements a secure-by-design microservice architecture with centralized authentication and authorization.
- API Gateway Security Model: Single entry point for all external requests with JWT token validation and revocation checking
- Token Management: JWT access tokens with refresh token rotation and immediate revocation on logout
- Service Isolation: Internal services are not directly exposed in production, accessed only through the secure API Gateway
- Audit Logging: Comprehensive security event logging with distributed tracing correlation
- Role-Based Access Control: JWT claims include user roles for fine-grained authorization
External Client β API Gateway (Port 8080) β Auth Service (Port 8083)
β
Internal Services (Ports 8081+)
Production Security:
- β Only API Gateway exposed externally
- β All requests validated for authentication and token revocation
- β Internal services trust gateway validation
- β Comprehensive audit trails for security events
Development Security:
β οΈ Direct service access allowed for testing/debuggingβ οΈ Must not be used for production workflows- β Same authentication and logging as production
- Security Architecture Guide: Complete security model, TokenRevocationChecker patterns, and service exposure guidelines
- Authentication Examples: API usage with JWT tokens, token refresh, and error handling
- Troubleshooting Auth: Debug authentication issues and token problems
This project is designed to be easily forkable. After forking:
-
Run the setup script with your new module path:
./scripts/setup-fork.sh github.com/yourusername/yourprojectname
-
Customize environment variables in
.env:DOCKER_PROJECT_PREFIX: Change fromservice-boilerplateto your preferred prefixDATABASE_NAME: Update fromservice_dbto your database nameAPI_GATEWAY_PORT,USER_SERVICE_PORT, etc.: Adjust service ports if neededJAEGER_UI_PORT,LOKI_PORT,GRAFANA_PORT: Change monitoring ports to avoid conflicts with other projects
Alternative: Use the automated Docker prefix script:
# Update development environment (default) ./scripts/update-docker-prefix.sh myproject # Update specific environment ./scripts/update-docker-prefix.sh prodproject .env.production
This automatically updates all Docker container names, volumes, and networks for the specified environment.
-
Start development:
make dev-bootstrap # For first-time setup with database
The setup script will update all Go module references and import paths automatically.
- Docker & Docker Compose (recommended)
- Go 1.23+ (for local development)
- PostgreSQL 15+ (for local development)
-
Quick start (Development with hot reload):
# π οΈ Bootstrap DEVELOPMENT environment with automatic database setup make dev-bootstrap # This automatically creates: # - Database tables and schemas for all services # - Dev admin account: [email protected] / devadmin123 (full admin access) # - Test users for development and testing # - Starts all services with hot reload and debug logging # Test basic authentication flow ./scripts/test-auth-flow.sh # Test RBAC (Role-Based Access Control) endpoints with dev admin account ./scripts/test-rbac-endpoints.sh # View distributed traces in Jaeger UI: # http://localhost:16686
Alternative: If you prefer manual control:
# Start services only (requires separate database setup) make dev # In another terminal, setup database: make db-migrate
-
Production deployment:
# π Start PRODUCTION environment with pre-built optimized images make prod # Run database migrations (required for production) make db-migrate
-
Environment commands:
# Check current environment status make status # View service logs make logs # Stop all services make down
β οΈ Important: Usemake devfor development/debugging andmake prodfor production. -
Interactive development menu:
./scripts/dev.sh
The project includes Air for hot reloading during development:
- Docker Hot Reload:
make dev- Services automatically restart on file changes
- Air: Live reloading for Go applications
- Development Script:
./scripts/dev.sh- Interactive development menu - Advanced Logging: See Logging System Documentation
- Health Checks: Automatic service health monitoring
- Environment Configuration: Flexible config management
For development and testing purposes, a pre-configured admin account is automatically created when you run make db-migrate:
- Email:
[email protected] - Password:
devadmin123 - Roles:
admin,user
This account has full administrative privileges and can be used to test RBAC functionality, manage roles/permissions, and perform administrative operations.
Example usage:
# Login as dev admin
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "devadmin123"}'
# Use JWT token for admin operations
./scripts/test-rbac-endpoints.sh-
Start all services with Air hot-reload:
make dev
-
View logs for running services:
make logs
-
Stop services:
make down
For production deployment with optimized Docker images:
-
Build and start production services:
# Build optimized production images and start services make build-prod # Build production images make prod # Start production containers
-
Switch from development to production:
# Stop development environment make down # Build and start production make build-prod make prod
-
Switch from production to development:
# Stop production environment make down # Build development images and start make build-dev make dev
| Mode | Build Target | Start Target | Hot Reload | Image Size |
|---|---|---|---|---|
| Development | make build-dev |
make dev |
β Air | ~1.2GB |
| Production | make build-prod |
make prod |
β None | ~15MB |
Note: Always run make down before switching between development and production modes to avoid image conflicts.
The API Gateway runs on http://localhost:8080 and proxies requests to individual services.
Health Check:
curl http://localhost:8080/healthCreate User:
curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '{
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe"
}'Get User:
curl http://localhost:8080/api/v1/users/1 \
-H "Authorization: Bearer your-token"List Users:
curl http://localhost:8080/api/v1/users \
-H "Authorization: Bearer your-token"Use the automated script to create new services:
make create-service SERVICE_NAME=product-service PORT=8082This will:
- Create the service directory structure
- Copy boilerplate code with proper naming
- Update docker-compose.yml
- Update Makefile targets
- Register with API gateway
# Primary Docker Commands
make dev # π οΈ Start DEVELOPMENT environment (hot reload, debug logs)
make prod # π Start PRODUCTION environment (pre-built images)
make smart-start # π§ Smart start - automatically detects environment
make down # Stop all services
make logs # View service logs
make status # Show current environment status
# Build Commands
make build-prod # Build production Docker images
make build-dev # Build development images with Air
make build # Build all services
# Database Commands
make db-migrate # Run database migrations
make db-setup # Complete database setup
make db-health # Check database connectivity
# Testing & Maintenance
make test # Run all tests
make clean # Clean build artifacts
make health # Comprehensive health check
make create-service # Create new serviceEach service has its own config.yaml file. Environment variables can override config values:
# Override database settings
export APP_DATABASE_HOST=prod-db.example.com
export APP_DATABASE_PASSWORD=secure-password
# Override server settings
export APP_SERVER_PORT=8080- cmd/: Application entry points
- internal/: Private application code
- handlers/: HTTP request handlers
- services/: Business logic layer
- repository/: Data access layer
- models/: Data structures
- pkg/: Public libraries
- migrations/: Database schema changes
Structured JSON logging is enabled by default:
logger.WithFields(logrus.Fields{
"user_id": 123,
"action": "login",
}).Info("User logged in")- Uses pgx driver with connection pooling
- Migrations managed with golang-migrate
- Repository pattern for data access
make test # Run all tests
make test-user-service # Run specific service testsmake build-prod # Build optimized production images
make prod # Start production environmentSet these for production:
APP_ENV=production
DATABASE_HOST=your-db-host
DATABASE_PASSWORD=your-secure-password
LOGGING_LEVEL=info- Follow the established code structure
- Add tests for new features
- Update documentation
- Use
make checkbefore committing
This project is licensed under the MIT License.