This template provides a production-ready foundation for building Go APIs. It makes opinionated choices about structure, tooling, and patterns—choices that have proven effective in real projects—while remaining flexible enough to adapt to your needs.
Every log line includes request_id and user_id (when authenticated). Trace any request from ingress to database and back. Sentry integration is pre-configured—just set SENTRY_DSN and get full stack traces, request context, and error grouping in production. No setup, no boilerplate, it just works.
Development uses MailHog—emails are captured locally at http://localhost:8025. Production uses SendGrid—flip one environment variable and you're sending real emails. Templates are built with React Email, so you write JSX components and get beautiful, tested HTML output.
User registration, login, logout, password reset, email verification—all implemented, tested, and secure. Account deletion includes a 30-day grace period (configurable), protecting users from accidental or malicious deletions. Tokens are SHA-256 hashed before storage. Passwords use bcrypt with configurable cost.
Three layers. That's it. Handlers receive HTTP requests. Services contain business logic. Repositories talk to the database. No managers, no adapters, no abstract factory factories. Your domain code lives in app/, infrastructure lives in support/. When you need to find something, you know where to look.
Hot reload out of the box—save a file, see the change. Swagger UI auto-generated from code annotations. Type-safe SQL via sqlc—write SQL, get Go structs. Compile-time DI via Wire—if it compiles, dependencies are satisfied. Configuration via Viper with environment variables, files, and sensible defaults.
Redis-backed job queue with Asynq. Automatic retries, scheduled tasks, dead letter queues. Email sending is already async—users don't wait for SMTP. Add your own jobs in minutes.
Rate limiting, graceful shutdown, health checks (database + Redis), CORS, panic recovery, request logging—all configured. Structured JSON logs ready for your log aggregator. Connection pooling tuned for real workloads.
Built for the age of AI-assisted development. Ships with a CLAUDE.md that teaches AI agents how your codebase works—build commands, architecture patterns, error handling conventions. The docs/ folder contains architecture.md and project-structure.md with the context AI agents need to make informed decisions. Claude Code, Cursor, Copilot—they all understand this codebase from day one.
This template values:
- Clarity over cleverness: Code should be obvious to the next developer
- Explicit dependencies: No global state, no magic injection
- Practical testing: Interfaces where they enable testing, not everywhere
- Minimal abstractions: Only add layers that earn their complexity
# Start infrastructure
docker compose up -d
# Install dependencies
make install
# Run database migrations
make migrate-up
# Start development server (hot reload)
make devThe API runs at http://localhost:8080. Swagger docs at http://localhost:8080/swagger/index.html.
| Component | Choice | Why |
|---|---|---|
| Framework | Echo | Fast, minimal, good middleware ecosystem |
| Database | PostgreSQL | Reliable, feature-rich, excellent tooling |
| SQL | sqlc | Type-safe queries, no ORM complexity |
| DI | Wire | Compile-time injection, clear dependency graph |
| Background Jobs | Asynq | Redis-backed, simple API, good reliability |
| Validation | go-playground/validator | Standard, declarative, extensible |
| Errors | eris | Stack traces, wrapping, better debugging |
.
├── api/ # HTTP layer (handlers, routes, request/response DTOs)
├── app/ # Application layer (services, repositories, domain errors)
├── cmd/ # CLI commands (api, worker, migrate)
├── db/ # Database (migrations, queries, generated code)
├── docs/ # Documentation
├── emails/ # Email templates (React Email)
└── support/ # Infrastructure (config, logging, middleware, DI)
See docs/project-structure.md for detailed package responsibilities.
# Development
make dev # Run API + Worker with hot reload
make run-api # Run API only
make run-worker # Run worker only
# Build & Quality
make build # Build binary (includes lint, fmt, generate)
make lint # Run linter
make generate # Regenerate code (sqlc, wire, mocks, swagger)
# Database
make migrate-up # Apply pending migrations
make migrate-down # Rollback last migration
make migrate-status # Show current migration version
make migrate-create name=add_users_table # Create new migration
# Testing
go test ./... # All tests
go test ./app/services/... # Single package
go test -run TestUserService ./... # Single test
go test -v -race ./... # Verbose with race detection
# Email Templates
make emails-dev # Preview email templates in browserConfiguration loads from environment variables (recommended) or config.yaml:
# Required for production
DATABASE_URL=postgres://user:pass@host:5432/dbname?sslmode=require
REDIS_ADDR=localhost:6379
AUTH_SECRET=your-secret-key-min-32-chars
# Email (choose one provider)
EMAIL_PROVIDER=sendgrid
EMAIL_SENDGRID_API_KEY=SG.xxx
# Or for development
EMAIL_PROVIDER=smtp
EMAIL_SMTP_HOST=localhost
EMAIL_SMTP_PORT=1025See support/config/config.go for all options with defaults.
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /users | Register new user | - |
| GET | /users/me | Get current user | Required |
| DELETE | /users/me | Schedule account deletion | Required |
| POST | /sessions | Login | - |
| DELETE | /sessions/current | Logout | Required |
| POST | /password-resets | Request password reset | - |
| PUT | /password-resets/:token | Complete password reset | - |
| POST | /email-verifications | Request verification email | Optional |
| PUT | /email-verifications/:token | Verify email | - |
| GET | /health | Health check | - |
See docs/architecture.md for:
- Layered architecture and data flow
- Dependency injection patterns
- Error handling strategy
- Background job processing
- Security considerations
- Define the interface in
app/interfaces/services/ - Implement the service in
app/services/ - Add repository if needed in
app/interfaces/repositories/andapp/repositories/ - Create handler in
api/handlers/ - Wire it up in
support/wire/wire.go - Add routes in
api/routes.go - Run
make generateto regenerate Wire code
- Define task type and payload in
app/tasks/ - Implement handler function
- Register in
app/tasks/registry.go - Enqueue from services via
TaskClient.EnqueueCtx()
make migrate-create name=add_notifications_table
# Edit db/migrations/XXXX_add_notifications_table.up.sql
# Edit db/migrations/XXXX_add_notifications_table.down.sql
make migrate-up- Unit tests: Services with mocked repositories (
app/services/*_test.go) - Repository tests: Against real database using testcontainers (
app/repositories/*_test.go) - Handler tests: HTTP tests with mocked services (
api/handlers/*_test.go)
Mocks are generated with mockery. Run make generate after changing interfaces.
Build the binary:
make build
./bin/go-reasonable-api api # Start API server
./bin/go-reasonable-api worker # Start background workerBoth processes should run concurrently in production. Use your orchestrator's process management or a process supervisor.
Required infrastructure:
- PostgreSQL 14+
- Redis 6+