Skeleton de API em Go — repository pattern, JWT, Redis, OpenTelemetry (Jaeger), scheduler e rate limit. Arquitetura espelhada no Laravel-skeleton, sem frontend.
Base sólida para APIs RESTful em Go de médio porte, incluindo:
- ✅ Arquitetura em camadas — Handler → Service → Repository → Model
- ✅ Repository pattern com interfaces — troca de backend sem tocar na lógica de negócio
- ✅ JWT Auth — guards separados por rota, role-based (admin/user)
- ✅ Rate limit — por IP, configurável por rota
- ✅ Redis — cache
- ✅ Scheduler — tarefas recorrentes em processo dedicado
- ✅ Observabilidade — OpenTelemetry → Jaeger (liga com uma env)
- ✅ Testes unitários e de integração — mocks hand-rolled, sem dependências externas
- ✅ Ambiente dockerizado — app + scheduler + MySQL + Redis + Jaeger prontos
/
├── docker-compose.yml # Orquestração dos serviços
├── Makefile # Atalhos para comandos comuns
├── .env.example # Variáveis de ambiente
├── docker/
│ ├── Dockerfile # Multi-stage build
│ └── otel-collector.yml # Config do OpenTelemetry collector
├── cmd/
│ ├── api/ main.go # Entrypoint da API
│ ├── scheduler/ main.go # Entrypoint do scheduler
│ └── migrate/ main.go # Entrypoint das migrations
├── migrations/
│ ├── migrate.go # AutoMigrate de todos os models
│ └── seed.go # Seeders (dados iniciais)
└── internal/
├── config/ # Carrega variáveis de ambiente
├── router/ # Rotas — equivalente ao routes/api.php
├── middleware/ # Auth JWT, AdminOnly, RateLimit, CORS, Logger
├── scheduler/ # Tarefas recorrentes
├── infra/
│ ├── database/ # Conexão GORM + MySQL
│ ├── redis/ # Conexão + RedisService
│ ├── mailer/ # SMTP
│ └── tracer/ # OpenTelemetry
└── domain/
└── user/ # Exemplo de domínio completo
├── model/ # Struct GORM
├── repository/ # Interface + implementação GORM
├── service/ # Lógica de negócio + erros sentinel
└── handler/ # HTTP handlers (Controllers)
cp .env.example .envSuba os containers:
docker compose up -ddocker exec -it go-skeleton-app sh./migratePara popular o banco com dados iniciais, edite migrations/seed.go e chame migrations.Seed(db) no entrypoint de migrate.
Usuários criados por padrão:
| Senha | Role | |
|---|---|---|
| admin@example.com | password | admin |
| alice@example.com | password | user |
| Serviço | URL |
|---|---|
| API | http://localhost:8020/api/v1 |
| Health | http://localhost:8020/health |
| MySQL | localhost:3306 |
| Redis | localhost:6379 |
| Jaeger UI | http://localhost:16686 |
POST /api/v1/auth/login # Autenticação — retorna JWT
POST /api/v1/auth/register # Cadastro
GET /api/v1/users # Listar usuários [JWT]
GET /api/v1/users/:id # Buscar por ID [JWT]
POST /api/v1/users # Criar usuário [JWT]
PUT /api/v1/users/:id # Atualizar usuário [JWT]
DELETE /api/v1/users/:id # Deletar usuário [JWT + admin]
GET /health # Health check
# Subir tudo
make up
# Rodar a API localmente (sem Docker)
make run
# Rodar scheduler localmente
make scheduler
# Rodar todos os testes
make test
# Testes com cobertura
make test-cover
# Lint (requer golangci-lint)
make lint
# Limpar dependências
make tidySiga o mesmo padrão do domínio user:
internal/domain/produto/
model/ produto.go # struct GORM
repository/ produto_repository.go # interface + impl
service/ produto_service.go # lógica de negócio
errors.go # erros sentinel
handler/ produto_handler.go # HTTP handlers
Registre no router em internal/router/router.go:
produtoRepo := repository.NewProdutoRepository(db)
produtoSvc := service.NewProdutoService(produtoRepo)
produtoHandler := handler.NewProdutoHandler(produtoSvc)
produtos := protected.Group("/produtos")
produtos.GET("", produtoHandler.List)
produtos.GET("/:id", produtoHandler.Show)
produtos.POST("", produtoHandler.Store)
produtos.PUT("/:id", produtoHandler.Update)
produtos.DELETE("/:id", middleware.AdminOnly(), produtoHandler.Destroy)Registre a migration em migrations/migrate.go:
db.AutoMigrate(&model.Produto{})Por padrão o Jaeger fica desligado. Para ativar:
OTEL_ENABLED=trueAcesse os traces em http://localhost:16686.
-
cp .env.example .env -
docker compose up -d -
docker exec -it go-skeleton-app /app/migrate - Testar
POST /api/v1/auth/logincomadmin@example.com/password
Pronto 🎉
Veja SECURITY.md.
MIT