Se você está desenvolvendo um projeto com Spring Boot e quer uma documentação automática e interativa da sua API, o Swagger com Springdoc OpenAPI é uma excelente escolha.

Neste artigo, vamos mostrar:

  • Como adicionar o Swagger ao projeto
  • Como corrigir incompatibilidades com o Spring Boot 3.4+
  • Como anotar seus endpoints
  • Como manter o DTO unificado para entrada e saída
  • Como validar os campos obrigatórios
  • Como garantir que os exemplos no Swagger reflitam os testes reais

🔧 Adicionando o Swagger ao projeto

Utilizamos a dependência recomendada do Springdoc:

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>

⚠️ Atenção à versão do Spring Boot!
Se você estiver usando a versão 3.4.x, ocorrerá o seguinte erro:

java.lang.NoSuchMethodError: 'void org.springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'

💡 Solução: Utilize o Spring Boot 3.2.5 para garantir compatibilidade.


🌐 Acessando a documentação interativa

Após subir a aplicação (localhost:8080), acesse:

http://localhost:8080/swagger-ui.html

Você verá todos os endpoints organizados com base nas anotações da sua aplicação.


📦 DTO único para entrada e saída

Utilizamos o mesmo DTO (ProdutoDTO) tanto para criação quanto para leitura de produtos. Isso simplifica o código e mantém a documentação clara.

Exemplo de JSON usado na criação:


{
"nome": "Casa de Alqueria D.O. Valle Central Carménère 2024",
"preco": 42.50,
"descricao": "Vinho chileno estruturado, ideal para jantares.",
"imgUrl": "",
"categorias": [
{ "id": 1 },
{ "id": 5 }
]
}

✅ Validando os campos obrigatórios

Adicionamos anotações de validação no DTO para garantir que os dados obrigatórios sejam respeitados:


@NotBlank(message = "Nome é obrigatório")

private String nome;

@NotNull(message = "Preço é obrigatório")
@Positive(message = "Preço deve ser maior que zero")
private Double preco;

@NotBlank(message = "Descrição é obrigatória")
private String descricao;

@NotEmpty(message = "Informe ao menos uma categoria")
private List<CategoriaDTO> categorias;

🔄 Método copyDtoToProduto

No serviço, garantimos que ao salvar ou atualizar, as categorias sejam carregadas corretamente com base nos IDs:

private void copyDtoToProduto(ProdutoDTO dto, Produto entity) {

entity.setNome(dto.getNome());
entity.setDescricao(dto.getDescricao());
entity.setPreco(dto.getPreco());
entity.setImgUrl(dto.getImgUrl());

entity.getCategorias().clear();
for (CategoriaDTO catDto : dto.getCategorias()) {
Categoria categoria = categoriaRepository.getReferenceById(catDto.getId());
entity.getCategorias().add(categoria);
}
}

📑 Anotações Swagger nos endpoints

Exemplo de documentação:


🛠 Tratamento de erros

Criamos um @ControllerAdvice para capturar exceções de validação e exibir erros amigáveis:

@ExceptionHandler(MethodArgumentNotValidException.class)

public ResponseEntity<ValidationError> handleValidationErrors(MethodArgumentNotValidException e, HttpServletRequest request) {
ValidationError err = new ValidationError(Instant.now(), 422, "Erro de validação", e.getMessage(), request.getRequestURI());
for (FieldError f : e.getBindingResult().getFieldErrors()) {
err.addError(f.getField(), f.getDefaultMessage());
}
return ResponseEntity.unprocessableEntity().body(err);
}

🎯 Conclusão

Com as práticas que mostramos neste artigo, você garante:

  • Documentação atualizada automaticamente
  • Validações robustas no backend
  • Exemplos coerentes com a realidade no Swagger
  • Facilidade de teste para equipes frontend

📺 Vídeo tutorial

Complementamos este conteúdo com um vídeo prático no canal do YouTube KaneChanDev: https://youtu.be/iMMm93r_baI

Categorized in:

Backend, Spring Boot,