Como lidar com respostas padronizadas e tratamento de erros.
RestApiResponseCustomProblemDetailGlobalExceptionHandlerErrorCategoryUse o helper RestApiResponse.success(data, links) nos
controllers base.
{
"status": "success",
"message": "Requisição realizada com sucesso",
"data": { /* payload */ },
"_links": {
"self": { "href": "https://api.exemplo.com/api/recurso/1" }
},
"timestamp": "2024-01-01T10:00:00"
}O contrato publico canonico usa _links em formato de
objeto por rel, nao links em array nem
envelope HAL completo com _embedded. Cada rel
aponta para um objeto de link unico ({ "href": "..." }) ou
para uma lista desses objetos quando houver multiplas ocorrencias para o
mesmo rel.
Erros são padronizados com CustomProblemDetail e
categorias (ErrorCategory).
{
"status": "failure",
"message": "Erro de validação",
"errors": [
{
"message": "Campo obrigatório",
"status": 400,
"title": "nome",
"type": "https://example.com/probs/validation-error",
"instance": "/api/human-resources/funcionarios",
"category": "VALIDATION"
}
],
"timestamp": "2024-01-01T10:00:00"
}GlobalExceptionHandler converte exceções comuns
(validação, not found, regra de negócio, etc.) em respostas
padronizadas.
MethodArgumentNotValidException → 400 com lista de
CustomProblemDetailMissingRequestHeaderException → 400 (header obrigatório
ausente)MissingServletRequestParameterException → 400
(parâmetro obrigatório ausente)ResponseStatusException → preserva status original
(ex.: 400/403/404/409/410/429/503), sem rebaixar para 500InvalidFilterPayloadException → 400 (payload de filtro
inválido)BusinessException → 400 com categoria
BUSINESS_LOGICEntityNotFoundException → 404IllegalArgumentException fora de validação explícita de
schema → 500 (evita mascarar erro interno como erro do cliente)Exception → 500ProblemDetail para
facilitar a UXtype para catálogos internos de
erros