"Documentação de API é o contrato entre backend e frontend. OpenAPI torna isso automático, sempre atualizado e testável." — #30DiasJava Developer Experience Notes
🎯 Objetivo do Day 21
Para facilitar o desenvolvimento e integração com a API, o Day 21 do #30DiasJava implementou documentação automática de APIs usando OpenAPI 3.0 e Swagger UI, com integração JWT, UI interativa e geração automática de especificações.
🛠️ O que foi implementado
✅ OpenAPI 3.0 Specification
- Automatic generation: Geração automática de especificação OpenAPI a partir de anotações
- SpringDoc OpenAPI: Integração com Spring Boot via SpringDoc
- API info: Informações da API (título, descrição, versão)
- Security schemes: Configuração de esquemas de segurança (JWT Bearer)
✅ Swagger UI
- Interactive UI: Interface web interativa para testar APIs
- Try it out: Testar endpoints diretamente do navegador
- Request/Response examples: Exemplos de requests e responses
- Authentication: Suporte para autenticação JWT na UI
✅ API Documentation
- Controller annotations: Documentação de controllers com
@Tag - Operation annotations: Documentação de operações com
@Operation - Parameter annotations: Documentação de parâmetros com
@Parameter - Response annotations: Documentação de responses com
@ApiResponse
✅ Security Integration
- JWT Bearer token: Configuração de autenticação JWT na documentação
- Security requirements: Requisitos de segurança por endpoint
- Token input: Campo para inserir token JWT na UI
📊 Arquitetura
┌─────────────────────────────────────────────────────────┐
│ Spring Boot Application │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Controllers com anotações OpenAPI │ │
│ │ @RestController, @Operation, @Tag │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ SpringDoc OpenAPI │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 1. Scan controllers e anotações │ │
│ │ 2. Gerar OpenAPI spec (JSON/YAML) │ │
│ │ 3. Expor Swagger UI │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ /swagger-ui │ │ /v3/api-docs │ │ OpenAPI │
│ (UI) │ │ (JSON) │ │ Spec │
└──────────────┘ └──────────────┘ └──────────────┘
💻 Implementação
Dependências (pom.xml)
<!-- OpenAPI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
</dependency>
OpenApiConfig
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI api() {
final String schemeName = "bearerAuth";
return new OpenAPI()
.info(new Info()
.title("Desafio das Águias API")
.description("Spring Boot + JWT + Missions")
.version("0.1.0"))
.addSecurityItem(new SecurityRequirement().addList(schemeName))
.components(new Components()
.addSecuritySchemes(schemeName, new SecurityScheme()
.name(schemeName)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")));
}
}
Controller Documentation Example
@RestController
@RequestMapping("/api/familias")
@Tag(name = "Familias", description = "API para gerenciamento de famílias")
public class FamiliaController {
@Autowired
private FamiliaService familiaService;
@GetMapping
@Operation(
summary = "Listar famílias",
description = "Retorna lista paginada de famílias com suporte a busca e ordenação"
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "Lista de famílias retornada com sucesso",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = FamiliaDTO.class)
)
),
@ApiResponse(
responseCode = "401",
description = "Não autenticado"
),
@ApiResponse(
responseCode = "403",
description = "Não autorizado"
)
})
public ResponseEntity<Page<FamiliaDTO>> listarFamilias(
@Parameter(description = "Termo de busca")
@RequestParam(required = false) String busca,
@Parameter(description = "Paginação")
Pageable pageable) {
Page<FamiliaDTO> familias = familiaService.listar(busca, pageable);
return ResponseEntity.ok(familias);
}
@PostMapping
@Operation(
summary = "Criar família",
description = "Cria uma nova família no sistema"
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "201",
description = "Família criada com sucesso"
),
@ApiResponse(
responseCode = "400",
description = "Dados inválidos"
)
})
@PreAuthorize("hasRole('USER')")
public ResponseEntity<FamiliaDTO> criarFamilia(
@Parameter(description = "Dados da família")
@Valid @RequestBody CriarFamiliaRequest request) {
FamiliaDTO familia = familiaService.criar(request);
return ResponseEntity.status(HttpStatus.CREATED).body(familia);
}
}
Configuration (application.yml)
springdoc:
api-docs:
enabled: true
path: /v3/api-docs
swagger-ui:
enabled: true
path: /swagger-ui
operations-sorter: method
tags-sorter: alpha
try-it-out-enabled: true
show-actuator: false
📈 Uso da Documentação
1. Acessar Swagger UI
http://localhost:8080/swagger-ui
A interface Swagger UI permite:
- Explorar endpoints: Ver todos os endpoints disponíveis
- Ver schemas: Ver modelos de dados (DTOs, Entities)
- Testar endpoints: Fazer requests diretamente da UI
- Autenticar: Inserir token JWT para testar endpoints protegidos
2. Obter OpenAPI Specification
# JSON format
curl http://localhost:8080/v3/api-docs
# YAML format (se configurado)
curl http://localhost:8080/v3/api-docs.yaml
3. Exemplo de OpenAPI Spec Gerado
{
"openapi": "3.0.1",
"info": {
"title": "Desafio das Águias API",
"description": "Spring Boot + JWT + Missions",
"version": "0.1.0"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Local server"
}
],
"paths": {
"/api/familias": {
"get": {
"summary": "Listar famílias",
"operationId": "listarFamilias",
"parameters": [
{
"name": "busca",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Lista de famílias retornada com sucesso"
}
},
"security": [
{
"bearerAuth": []
}
]
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
}
}
}
4. Usar Token JWT na UI
- Fazer login via
/auth/loginpara obter token - Clicar em "Authorize" no topo da Swagger UI
- Inserir token no formato:
Bearer <token> - Agora todos os endpoints protegidos podem ser testados
🎓 Lições Aprendidas
✅ O que funcionou bem
- Documentação automática: Anotações geram documentação automaticamente
- Sempre atualizada: Documentação reflete código atual (sem desatualização)
- UI interativa: Swagger UI permite testar APIs sem Postman/curl
- JWT integration: Autenticação JWT funciona perfeitamente na UI
⚠️ Desafios e soluções
- Anotações verbosas: Muitas anotações podem poluir código. Solução: Usar apenas onde necessário, manter código limpo.
- Schemas complexos: DTOs complexos podem gerar specs grandes. Solução: Usar
@Schemapara simplificar. - Versionamento: OpenAPI spec muda com código. Solução: Versionar spec junto com código.
📚 Recursos
- SpringDoc OpenAPI: https://springdoc.org/
- OpenAPI Specification: https://swagger.io/specification/
- Swagger UI: https://swagger.io/tools/swagger-ui/
- OpenAPI Generator: https://openapi-generator.tech/ (gerar client SDKs)
🔗 Links
Next episode → Day 22/30 — Em desenvolvimento