📑 Padrões de Desenvolvimento – Backend
Esta página visa apresentar os padrões a serem utilizados no desenvolvimento de código do repositório do Backend da aplicação.
Sumário
Swagger
Além de seguir os padrões determinados pela arquitetura e estrutura de pastas do projeto, é necessário atualizar a estrutura do Swagger conforme é realizado o desenvolvimento da aplicação.
🔑 Fluxo de uso do Swagger com Login e Token
-
Abrir o Swagger
- Acesse no navegador o link:
👉 http://localhost:8080/swagger-ui/index.html
- Acesse no navegador o link:
-
Localizar o endpoint de Login
- Na lista de endpoints, procure pelo recurso
/login
. - Clique nele para expandir os detalhes.
- Na lista de endpoints, procure pelo recurso
-
Executar o Login
- Clique no botão
Try it out
. - Será exibido um corpo JSON no campo de request body, parecido com:
{ "user": "string", "senha": "string" }
- Substitua os valores de
"string"
pelos dados que estão cadastrados no banco, por exemplo:{ "user": "[email protected]", "senha": "Senha" }
- Clique em Execute.
- Clique no botão
- Obter o Token
- A resposta da requisição conterá um campo
token
. - Copie apenas o valor do token, ou seja, o texto que aparece entre as aspas após
"token":"
.
-
Autorizar o Swagger
- No canto superior direito do Swagger, clique no botão Authorize (ícone de cadeado
🔒 ). - Vai abrir um modal pedindo o token de autenticação.
- Cole o token copiado.
- Confirme clicando em Authorize e depois Close.
- No canto superior direito do Swagger, clique no botão Authorize (ícone de cadeado
-
Usar os Endpoints Protegidos
- Agora todos os endpoints que exigem autenticação já estarão configurados para enviar o token no header (
Authorization: Bearer <token>
). - Basta navegar pelos endpoints, clicar em Try it out e executar normalmente.
- Agora todos os endpoints que exigem autenticação já estarão configurados para enviar o token no header (
As marcações do Swagger devem ser inseridas em:
- Controllers
- Models
- DTOs
📌 DTOs
- Todos os DTOs devem ser criados na pasta
dto
do seu modulo. - Para a criação dos DTOs usamos a anotação
@Valid
para validar o tipo de um atributo . - Utilizar o Bean Validation do Spring para validação automática de atributos.
- As anotações de validação devem ser aplicadas diretamente nos atributos do DTO.
Exemplo:
public class UsuarioDTO {
@NotBlank(message = "O nome é obrigatório")
private String nome;
@Email(message = "E-mail deve ser válido")
private String email;
@NotNull(message = "A idade é obrigatória")
@Min(value = 18, message = "Idade mínima é 18 anos")
private Integer idade;
}
Na Controller:
@PostMapping
public ResponseEntity<UsuarioDTO> salvar(@RequestBody @Valid UsuarioDTO usuarioDTO) {
return ResponseEntity.ok(service.salvar(usuarioDTO));
}
Estrutura de Exceções
-
exception/HttpException.java
→ classe base -
exception/NotFoundException.java
→ exemplo de exceção específica -
config/GlobalExceptionHandler.java
→ handler global
Handler Global: GlobalExceptionHandler
- O handler global (GlobalExceptionHandler) captura todas as exceções e retorna respostas padronizadas:
- HttpException → retorna a mensagem e o status HTTP definido na exceção
- Exception → erros genéricos retornam 500 com mensagem padrão
- MethodArgumentNotValidException → validação de DTOs retorna 400 BAD_REQUEST com detalhes de cada campo
- IllegalArgumentException → retorna 400 BAD_REQUEST com mensagem da exceção
1. Criando Exceções
Todas as exceções personalizadas devem estender HttpException
.
public class NotFoundException extends HttpException {
public NotFoundException(String message) {
super(message, HttpStatus.NOT_FOUND);
}
}
Exemplo de Uso:
@GetMapping("/usuarios/{id}")
public Usuario getUsuario(@PathVariable Long id) {
return usuarioRepository.findById(id)
.orElseThrow(() -> new NotFoundException("Usuário não encontrado"));
}
Retorno :
{
"message": "Usuário não encontrado",
"status": "NOT_FOUND"
}
🔹 Padrão de Código: @Get (Controller + Service)
- A requisição chega no Controller e chama o método da service para buscar todas as instâncias no banco de dados.
- O método cityService.getAllCities() é chamado. 3.A resposta é devolvida em formato JSON contendo a lista de CityResponseDTO.
Classe Controller
@GetMapping
@Operation(summary = "Get All Services",
description = "Returns a list of all services available in the system")
@ApiResponse(responseCode = "200", description = "Cities retrieved successfully")
public ResponseEntity<List<CityResponseDTO>> getAllCities() {
List<CityResponseDTO> cities = cityService.getAllCities();
return ResponseEntity.ok(cities);
}
Classe Service
public List<CityResponseDTO> getAllCities() {
List<City> cities = cityRepository.findAll();
return cities.stream()
.map(city -> new CityResponseDTO(city.getId(), city.getName(), city.getState()))
.toList();
}
Get By id
Classe Controller
@GetMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<UserResponseDTO> getUser(@PathVariable UUID id) {
return ResponseEntity.ok(service.getUserById(id));
}
Na service
@Transactional
public UserResponseDTO getUserById(UUID id) {
User user = userRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
return modelMapper.map(user, UserResponseDTO.class);
}
Boas Práticas de Exceções
- Sempre criar exceções específicas estendendo
HttpException
. - Usar mensagens claras e descritivas.
- Não lançar
RuntimeException
direto; use suas exceções customizadas. - Validações de DTO são tratadas automaticamente (
@Valid
). - Não manipular a resposta JSON de erro manualmente; o handler global cuida disso.