Mensagens de Erro Estruturadas para APIs HTTP
November 2, 2022
Desde que comecei a trabalhar no projeto Apache APISIX, tenho tentado melhorar meu conhecimento e compreensão de APIs REST RESTful HTTP. Para isso, estou lendo e assistindo às seguintes fontes:
- Livros. No momento, estou terminando API Design Patterns. Esperem uma resenha em breve.
- YouTube. Recomendo o canal de Erik Wilde. Embora alguns vídeos sejam melhores que outros, todos focam em APIs.
- IETF RFCs. A maioria dos RFCs não trata de APIs, mas uma pessoa gentil compilou uma lista dos que tratam.
Hoje, gostaria de apresentar o RFC "Problem Details for HTTP APIs", também conhecido como RFC 7807.
O(s) problema(s)
Os princípios REST exigem o uso de status HTTP para comunicação. Para erros, o HTTP define dois intervalos: erros do cliente, 4xx
, e erros do servidor, 5xx
.
Imagine uma API bancária que permite que você faça transferências. Ela deve falhar se você tentar transferir mais fundos do que possui em sua conta. Alguns códigos de status HTTP podem se encaixar:
400 Bad Request
: O servidor não pode ou não processará a solicitação devido a algo que é percebido como um erro do cliente.402 Payment Required
: A solicitação não pode ser processada até que o cliente faça um pagamento. No entanto, não existe uma convenção de uso padrão, e diferentes entidades a usam em outros contextos.409 Conflict
: A solicitação entra em conflito com o estado atual do recurso de destino.
Aqui está o primeiro problema: os códigos de status HTTP foram especificados para interações humano-máquina via navegadores, não para interações máquina-máquina via APIs. Portanto, selecionar um código de status que mapeie diretamente para o caso de uso raramente é simples. Para registro, Martin Fowler parece favorecer o 409 no nosso caso.
Qualquer que seja o código de status, o segundo problema diz respeito ao payload de erro ou, mais precisamente, à sua estrutura. A estrutura não é importante se uma única organização gerencia o cliente e o provedor da API. Mesmo que uma equipe dedicada desenvolva cada um deles, eles podem se alinhar. Por exemplo, imagine um aplicativo móvel que chama sua própria API.
No entanto, problemas surgem quando uma equipe decide usar uma API de terceiros. A escolha da estrutura de resposta é significativa nesse caso, pois agora é considerada parte de um contrato: qualquer mudança do provedor pode quebrar os clientes. Pior, a estrutura provavelmente será diferente de provedor para provedor.
Portanto, uma estrutura padronizada de relatório de erros:
- Fornece uniformidade entre provedores
- Aumenta a estabilidade da API
RFC 7807
RFC 7807 visa resolver o problema fornecendo uma estrutura de erro padronizada.
A estrutura é a seguinte:
O RFC descreve os campos:
"type"
(string
) - Uma referência URI [RFC3986] que identifica o tipo de problema. Esta especificação incentiva que, quando desreferenciada, forneça documentação legível por humanos para o tipo de problema (e.g., usando HTML [W3C.REC-html5-20141028]). Quando este membro não estiver presente, seu valor é assumido como"about:blank"
."title"
(string
) - Um resumo curto e legível por humanos do tipo de problema. NÃO DEVE mudar de ocorrência para ocorrência do problema, exceto para fins de localização (e.g., usando negociação de conteúdo proativa; veja [RFC7231, Seção 3.4])."status"
(number
) - O ([RFC7231], Seção 6) gerado pelo servidor de origem para esta ocorrência do problema."detail"
(string
) - Uma explicação legível por humanos específica para esta ocorrência do problema."instance"
(string
) - Uma referência URI que identifica a ocorrência específica do problema. Pode ou não fornecer mais informações se desreferenciada.
O RFC oferece o seguinte exemplo quando não há fundos suficientes para fazer uma transferência bancária.
Um exemplo
Vou usar um dos meus demos existentes como exemplo. O demo destaca várias etapas para facilitar o processo de evolução de suas APIs.
Na etapa 6, quero que os usuários se registrem, então limito o número de chamadas em uma janela de tempo se eles não estiverem autenticados. Criei um plugin dedicado do Apache APISIX para isso. Após o número de chamadas atingir o limite, ele retorna:
HTTP/1.1 429 Too Many Requests
Date: Fri, 28 Oct 2022 11:56:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.15.0
{"error_msg":"Por favor, registre-se em https:\/\/apisix.org\/register para obter seu token de API e desfrutar de chamadas ilimitadas"}
Vamos estruturar a mensagem de acordo com o RFC 7807.
Conclusão
O RFC 7807 não apenas ajuda os desenvolvedores de clientes. É uma grande ajuda para os implementadores de APIs, pois fornece diretrizes rápidas para evitar reinventar a roda em cada projeto.
Vá mais longe:
Publicado originalmente em A Java Geek em 30 de outubro de 2022