A production-ready Go web service starter template featuring clean architecture, comprehensive testing, and scalable design patterns. Built with modern Go practices and industry-standard tools.
This project serves as a comprehensive starter template for building scalable Go web services. It demonstrates:
- Clean Architecture with dependency injection
- Comprehensive Testing Strategy (unit, integration, performance)
- Production-Ready Patterns for real-world applications
- Scalable Design that grows with your needs
- Industry Best Practices from the Go community
Perfect for developers who want to start with a solid foundation rather than building everything from scratch.
- Clean separation of concerns (handlers, business logic, data layer)
- Dependency injection for testability and flexibility
- Interface-driven design for easy extension and testing
- Thread-safe operations with proper concurrency handling
- 100% test coverage on critical components
- Table-driven tests for comprehensive scenario coverage
- Mock-based testing for isolated unit tests
- Integration tests with real HTTP workflows
- Performance benchmarks and race condition detection
- Hot reload development setup
- Automated testing with comprehensive Makefile
- API documentation with Swagger/OpenAPI
- Code quality tools integration ready
- Structured logging with Gin middleware
- Error handling with consistent HTTP responses
- Performance optimized with benchmark validation
- Concurrent access safely handled
- Go 1.21 or higher
- Git
# Clone or download this template
git clone <your-repo-url>
cd go-api-example
# Generate Open API docs
make docs
# Install dependencies
make deps
# Run tests to verify setup
make test
# Start development server
make runThe API will be available at http://localhost:8080
# Check API health
curl http://localhost:8080/api/v1/users
# View interactive API documentation
open http://localhost:8080/swagger/index.htmlβββ api # open api + swagger docs are generated here
βββ build # build configuration
βββ configs # service configuration
βββ deployments # deployment configuration - currently only docker-compose
βββ go.mod
βββ go.sum
βββ internal
β βββ app
β β βββ app.go # top-level application service setup
β βββ config
β β βββ config.go # application configuration types and reader
β βββ handlers # web service handlers
β β βββ users.go
β β βββ users_test.go
β βββ middleware # to be used for functionality such authentication
β βββ store # user storage
β βββ memory.go # in-memory implementation of UserStore
β βββ memory_test.go
β βββ user.go # User and UserStore types
βββ LICENSE
βββ Makefile # Script for various tasks: docs, deps, build, test, test-unit etc
βββ README.md # This file
βββ scripts # Various scripts used for building and testing
βββ TESTING.md # Testing documentation
graph TD
A[HTTP Requests] --> B[Gin Router]
B --> C[User Handlers]
C --> D[UserStore Interface]
D --> E[MemoryUserStore]
D --> F[DatabaseUserStore*]
D --> G[CacheUserStore*]
H[Tests] --> C
H --> E
*Future implementations
| Method | Endpoint | Description | Status |
|---|---|---|---|
GET |
/api/v1/users |
List all users | β |
GET |
/api/v1/users/{id} |
Get user by ID | β |
POST |
/api/v1/users |
Create new user | β |
PUT |
/api/v1/users/{id} |
Update user | β |
DELETE |
/api/v1/users/{id} |
Delete user | β |
# Create a user
curl -X POST http://localhost:8080/api/v1/users \
-H "Content-Type: application/json" \
-d '{"name":"John Doe","email":"john@example.com"}'
# Get all users
curl http://localhost:8080/api/v1/users
# Get specific user
curl http://localhost:8080/api/v1/users/1
# Update user
curl -X PUT http://localhost:8080/api/v1/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Jane Doe","email":"jane@example.com"}'
# Delete user
curl -X DELETE http://localhost:8080/api/v1/users/1// Success Response
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
// Error Response
{
"error": "User not found"
}This project demonstrates comprehensive testing practices for Go web services.
- Store Package: 100% coverage
- Handler Package: 62.5% coverage
- Integration Tests: Full CRUD workflows
- Performance Tests: Benchmark all operations
# Run all tests
make test
# Run specific test categories
make test-unit # Unit tests only
make test-integration # Integration tests
make test-coverage # Generate coverage report
make benchmark # Performance benchmarks
make test-race # Race condition detection
# Run specific packages
go test ./store/... # Store tests only
go test ./handlers/... # Handler tests onlyBenchmarkMemoryUserStore_Create-16 337.3 ns/op 273 B/op 1 allocs/op
BenchmarkMemoryUserStore_GetByID-16 30.11 ns/op 48 B/op 1 allocs/op
BenchmarkMemoryUserStore_GetAll-16 11680 ns/op 40960 B/op 1 allocs/op
BenchmarkMemoryUserStore_ConcurrentReads-16 919.9 ns/op 4096 B/op 1 allocs/op
See TESTING.md for detailed testing documentation.
# Development
make dev # Start development server (alias for run)
make run # Build and run the application
make build # Build binary executable
# Testing & Quality
make test # Run all tests
make test-coverage # Generate HTML coverage report
make benchmark # Run performance benchmarks
make test-race # Test with race detection
make lint # Run code linting (installs golangci-lint)
# Documentation
make docs # Generate/update Swagger documentation
# Maintenance
make deps # Install/update dependencies
make clean # Clean build artifacts and test cache
make ci # Run full CI pipeline (deps, test, race, coverage, lint)-
Add new features:
# Create feature branch git checkout -b feature/new-endpoint # Develop with hot reload make run
-
Write tests first (TDD approach):
# Add tests # Run tests frequently make test-unit
-
Verify quality:
# Full test suite make ci -
Update documentation:
# Regenerate API docs make docs
-
Create database implementation:
// store/postgres.go type PostgresUserStore struct { db *sql.DB } func (p *PostgresUserStore) GetAll() ([]User, error) { // Implementation }
-
Update main.go:
// Switch implementations userStore := store.NewPostgresUserStore(db)
-
Add tests:
// store/postgres_test.go func TestPostgresUserStore_Integration(t *testing.T) { // Integration tests with test database }
-
Define in handlers:
// handlers/users.go func (h *UserHandler) SearchUsers(c *gin.Context) { // Implementation with store interface }
-
Add route in main.go:
v1.GET("/users/search", userHandler.SearchUsers)
-
Write comprehensive tests:
// handlers/users_test.go func TestUserHandler_SearchUsers(t *testing.T) { // Table-driven tests }
// middleware/auth.go
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Authentication logic
c.Next()
}
}
// main.go
v1.Use(middleware.AuthMiddleware())- Testify - Testing toolkit with assertions and mocks
- golangci-lint - Code quality and linting
All dependencies are pinned to stable versions for reliability.
# Dockerfile (example)
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o api-server main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/api-server .
EXPOSE 8080
CMD ["./api-server"]# k8s/deployment.yaml (example)
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-api
spec:
replicas: 3
selector:
matchLabels:
app: go-api
template:
metadata:
labels:
app: go-api
spec:
containers:
- name: api
image: go-api:latest
ports:
- containerPort: 8080# .github/workflows/ci.yml (example)
name: CI/CD Pipeline
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: '1.21'
- run: make ci
- run: make build- Interface Segregation - Small, focused interfaces
- Dependency Inversion - Depend on abstractions, not concretions
- Single Responsibility - Each component has one clear purpose
- Open/Closed - Open for extension, closed for modification
- Test-Driven - Tests guide design and catch regressions
- Repository Pattern -
UserStoreinterface abstracts data access - Dependency Injection - Components receive dependencies, don't create them
- Table-Driven Testing - Comprehensive test scenarios with minimal code
- Factory Pattern - Constructor functions for clean initialization
- Middleware Pattern - Composable request processing
- Go Standards - Following official Go conventions
- Clear Naming - Self-documenting code with meaningful names
- Error Handling - Explicit error handling at every level
- Documentation - Comprehensive comments and examples
We welcome contributions! This starter template benefits from community improvements.
- Fork & Clone the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Write tests first for new functionality
- Ensure all tests pass:
make ci - Update documentation if needed
- Submit pull request with clear description
- Tests added for new functionality
- All existing tests pass (
make test) - No race conditions (
make test-race) - Documentation updated
- Code follows Go conventions
- Commit messages are clear
This project is licensed under the MIT License - see the LICENSE file for details.
- Go Team - For creating an excellent language and toolchain
- Gin Framework - For the lightweight, fast HTTP framework
- Testify - For making Go testing more enjoyable
- Go Community - For best practices and patterns demonstrated here
- Effective Go - Official Go best practices
- Go Code Review Comments - Style guide
- Advanced Go Patterns - Advanced techniques
- Awesome Go - Curated Go resources
- Go Report Card - Code quality analysis
- pkg.go.dev - Go package documentation
Ready to build something amazing? π
This starter template gives you a solid foundation. Focus on your business logic while we handle the boilerplate, testing, and architectural patterns.
Star β this repository if it helps you build better Go services!