Template padrão para APIs Spring Boot da empresa. Contém toda a infraestrutura base, padrões de código, segurança, logging, CI/CD e um módulo de exemplo completo para referência.
| Tecnologia | Versão | Propósito |
|---|---|---|
| Java | 17 | Linguagem |
| Spring Boot | 3.2.2 | Framework |
| Spring Security | 6.x | Autenticação JWT |
| Spring Data JPA | 3.x | Persistência |
| SQL Server | - | Banco de dados |
| auth0 java-jwt | 4.2.1 | Validação de tokens JWT |
| SpringDoc OpenAPI | 2.0.2 | Documentação Swagger |
| WebClient (WebFlux) | - | Comunicação entre microsserviços |
| Apache POI | 5.0.0 | Geração de relatórios Excel |
| Caffeine | 3.1.8 | Cache em memória |
| spring-dotenv | 3.0.0 | Variáveis de ambiente via .env |
| Maven | 3.9+ | Build |
- JDK 17+
- Maven 3.9+ (ou usar o wrapper
./mvnwincluso) - SQL Server acessível
- Serviço de autenticação (API que emite tokens JWT com issuer "API Autenticacao")
# 1. Clone ou copie este template
git clone <url-do-template> meu-novo-projeto
cd meu-novo-projeto
# 2. Configure as variáveis de ambiente
cp .env.example .env
# Edite .env com suas credenciais
# 3. Configure o application.properties
cp src/main/resources/application.properties.example src/main/resources/application.properties
# 4. Build
./mvnw clean package -DskipTests
# 5. Run
./mvnw spring-boot:runA API estará disponível em http://localhost:8080.
Swagger UI em http://localhost:8080/swagger-ui.html.
| Variável | Descrição | Exemplo |
|---|---|---|
DB_URL |
JDBC connection string do SQL Server | jdbc:sqlserver://localhost:1433;databaseName=MINHA_DB;encrypt=true;trustServerCertificate=true |
DB_USERNAME |
Usuário do banco | sa |
DB_PASSWORD |
Senha do banco | MinhaSenh@123 |
JWT_SECRET |
Chave secreta para validação do token JWT | minha-chave-secreta-256-bits |
AUTHENTICATOR_URL |
URL base do serviço de autenticação | http://localhost:9090/authenticator |
SERVER_PORT |
Porta da aplicação | 8080 |
# Build (gera JAR em target/TEMPLATE.jar)
./mvnw clean package -DskipTests
# Run em desenvolvimento
./mvnw spring-boot:run
# Rodar testes
./mvnw test
# Apenas compilar (verificar erros)
./mvnw clean compilesrc/main/java/com/br/template/
├── TemplateApplication.java # Entry point
│
├── authentication/ # Segurança JWT
│ ├── SecurityConfigurations.java # Configuração do Spring Security
│ ├── SecurityFilter.java # Filtro que valida token em cada request
│ └── TokenService.java # Validação e extração de dados do JWT
│
├── config/ # Configurações transversais
│ ├── CorsConfiguration.java # Origens permitidas (CORS)
│ ├── ErrorDetails.java # Handler global de exceções (@RestControllerAdvice)
│ ├── LoggingInterceptor.java # Log de request/response com duração e request-id
│ ├── SpringDocConfigurations.java # Configuração do Swagger/OpenAPI
│ ├── SuccessDetails.java # Wrapper para respostas de sucesso
│ ├── WebClientConfig.java # WebClient com propagação automática de token
│ └── WebConfig.java # Registro de interceptors
│
├── controller/ # REST Controllers
│ └── SampleController.java # Exemplo: CRUD com filtros e paginação
│
├── dto/ # Objetos de resposta
│ └── SampleResponse.java # Exemplo: mapeamento entity → response
│
├── enums/ # Enumerações de domínio
│ └── Status.java # Exemplo: StatusSampleEnum
│
├── filtro/ # Filtros dinâmicos
│ ├── SampleFilters.java # Exemplo: orquestrador de Specifications
│ └── specification/
│ └── SampleSpecification.java # Exemplo: métodos estáticos de filtro
│
├── form/ # Objetos de entrada (request)
│ └── SampleRequest.java # Exemplo: com Bean Validation
│
├── models/ # Entidades JPA
│ ├── Sample.java # Exemplo: entidade com timestamps
│ └── User.java # Modelo de usuário (do serviço de autenticação)
│
├── repository/ # Repositórios Spring Data
│ └── SampleRepository.java # Exemplo: JpaRepository + JpaSpecificationExecutor
│
├── service/ # Lógica de negócio
│ ├── SampleService.java # Exemplo: CRUD completo
│ └── UserService.java # Resolução de usuários via API externa + cache
│
└── utils/ # Utilitários compartilhados
HTTP Request
→ SecurityFilter (valida JWT)
→ LoggingInterceptor (loga início)
→ Controller (traduz HTTP → service call)
→ Service (lógica de negócio, @Transactional)
→ Repository (JPA)
→ Filters + Specification (filtros dinâmicos)
→ UserService (resolve usuários externos)
→ Controller (monta Response DTO)
→ LoggingInterceptor (loga fim + duração)
HTTP Response
- Token JWT validado em cada request pelo
SecurityFilter - Token pode vir via:
- Cookie
token(aplicações web) - Header
Authorization: Bearer <token>(APIs/mobile)
- Cookie
- Endpoints públicos:
/swagger-ui/**,/v3/api-docs/** - O token é emitido por um serviço externo (autenticador) — esta API apenas valida
Para listagens com filtros opcionais:
*Specification— classe com métodos estáticos que retornamSpecification<Entity>*Filters—@Serviceque monta a query combinando Specifications condicionalmente- Controller — recebe
@RequestParam(required = false)e delega ao service
Controller (params opcionais) → Service → Filters → Specification → Repository.findAll(spec, pageable)
Usuários são externos (vivem no serviço de autenticação). Nas entidades, armazenamos apenas o Long fk_Id_User. Para exibir dados do usuário nas responses:
- Coletar todos os IDs de usuário da página
- Chamar
UserService.getUsuariosByIds(ids)(batch, com cache Caffeine de 5min) - Montar o Response DTO com o mapa de usuários
Exceções são tratadas globalmente pelo ErrorDetails (@RestControllerAdvice):
| Exceção | HTTP Status |
|---|---|
EntityNotFoundException |
404 |
IllegalArgumentException |
400 |
DataIntegrityViolationException |
409 |
AccessDeniedException |
401 |
MethodArgumentNotValidException |
400 (com lista de erros) |
Formato da resposta de erro:
{
"timestamp": "2026-06-01T10:30:00",
"message": ["Registro não encontrado com id: 42"]
}Siga a ordem abaixo (ou use o agent scaffold):
@Entity
@Table(name = "tbMeuModulo")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class MeuModulo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@Enumerated(EnumType.STRING)
private StatusMeuModuloEnum status;
@Column(name = "fk_Id_User")
private Long creationUser;
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@PrePersist
private void prePersist() { ... }
@PreUpdate
private void preUpdate() { ... }
// getters + setters
}Adicionar inner enum:
public static enum StatusMeuModuloEnum {
PENDING, IN_PROGRESS, COMPLETED, CANCELLED;
}@Repository
public interface MeuModuloRepository extends JpaRepository<MeuModulo, Long>, JpaSpecificationExecutor<MeuModulo> {
}Métodos estáticos para cada filtro.
@Service que combina Specifications.
Campos com validação. Apenas getters.
Construtor que mapeia entity + users. Apenas getters.
CRUD com @Transactional nas mutações.
Endpoints REST com @Valid, Pageable, filtros opcionais.
O workflow .github/workflows/main.yml executa em push/PR para main e dev:
- Build —
mvn clean package -DskipTests - Stop — Para o serviço Windows no servidor via SSH
- Deploy — Envia o JAR via SCP
- Start — Inicia o serviço Windows via SSH
| Tipo | Nome | Descrição |
|---|---|---|
| Variable | HOST |
IP/hostname do servidor |
| Variable | USER |
Usuário SSH |
| Variable | SERVICE_NAME |
Nome do serviço Windows (ex: backend-meu-projeto) |
| Variable | DEPLOY_PATH |
Caminho de destino do JAR (ex: C:/Sistemas/Backend/API/jar) |
| Secret | SSH_KEY |
Chave privada SSH |
| Secret | PASSPHRASE |
Passphrase da chave SSH |
prod— ativado em push paramaindev— ativado em push paradev
O template inclui skills e agents em .claude/ para padronizar o desenvolvimento assistido por IA.
| Skill | Quando usar |
|---|---|
back-end |
Qualquer tarefa de backend (orquestrador) |
architecture |
Estrutura de pacotes, decisões arquiteturais |
controller |
Criar/revisar controllers |
service |
Criar/revisar services |
repository |
Criar/revisar repositories e Specifications |
dto-entity |
Criar/revisar DTOs e entidades |
exceptions |
Error handling |
validation |
Bean Validation |
swagger |
Documentação OpenAPI |
code-style |
Estilo de código, proibições |
| Agent | Propósito |
|---|---|
scaffold |
Gera estrutura completa de novo módulo (9 arquivos) |
code-reviewer |
Revisa código buscando bugs, performance e violações |
- Renomear pacote
com.br.template→com.br.<nome-do-projeto> - Atualizar
pom.xml:artifactId,name,description,<finalName> - Copiar
.env.example→.enve preencher - Copiar
application.properties.example→src/main/resources/application.properties - Atualizar
SpringDocConfigurations.java(título e descrição da API) - Atualizar
CorsConfiguration.java(origens permitidas) - Atualizar
.github/workflows/main.yml(variáveis de deploy) - Remover o módulo de exemplo
Sample(ou renomear para o primeiro módulo real) - Criar o banco de dados no SQL Server
- Testar:
./mvnw spring-boot:run+ acessar Swagger
| Regra | Detalhe |
|---|---|
| Sem Lombok | Getters/setters manuais |
| Constructor injection | Nunca @Autowired em campos |
| Timestamps automáticos | @PrePersist / @PreUpdate |
Tabelas com prefixo tb |
tbProject, tbDelivery |
| Filtros via Specification | Nunca JPQL dinâmico |
| Usuários externos | Armazenar só o ID, resolver via UserService |
| Erros via exceção | Nunca montar ResponseEntity de erro manualmente |
| Swagger em português | @Operation, @Schema |
| Mensagens de erro em português | User-facing |
| Classes em inglês | ProjectController, SampleService |
| Métodos de negócio em português | buscar, registrar, atualizar, deletar |