Boas práticas de retorno de erros da API REST

Estou procurando orientação sobre boas práticas quando se trata de retornar erros de uma API REST. Estou trabalhando em uma nova API para poder tomar uma direção agora. Meu tipo de conteúdo é XML no momento, mas pretendo suportar o JSON no futuro.

Agora estou adicionando alguns casos de erro, como por exemplo, um cliente tenta adicionar um novo recurso, mas excedeu sua cota de armazenamento. Eu já estou lidando com certos casos de erro com códigos de status HTTP (401 para autenticação, 403 para autorização e 404 para URIs simples de solicitação inválida). Eu olhei sobre os abençoados códigos de erro HTTP, mas nenhum dos intervalos de 400-417 parece correto para relatar erros específicos do aplicativo. Então, no começo, fiquei tentada a retornar o erro do meu aplicativo com 200 OK e uma carga XML específica (ou seja, pague mais e você terá o armazenamento necessário!), Mas parei para pensar nisso e parece encolher de ombros). Além disso, parece que estou dividindo as respostas de erro em casos distintos, já que alguns são orientados pelo código de status http e outros são orientados por conteúdo.

Então, quais são as recomendações do setor? Boas práticas (por favor, explique por quê!) E também, a partir de um cliente pov, que tipo de manipulação de erros na API REST facilita a vida do código do cliente?

Então, no começo, fiquei tentada a retornar o erro do meu aplicativo com 200 OK e uma carga XML específica (ou seja, pague mais e você terá o armazenamento necessário!), Mas parei para pensar nisso e parece encolher de ombros).

Eu não retornaria um 200 a menos que realmente não houvesse nada de errado com o pedido. De RFC2616 , 200 significa “a solicitação foi bem-sucedida”.

Se a cota de armazenamento do cliente foi excedida (por qualquer motivo), eu retornaria um 403 (Proibido):

O servidor entendeu o pedido, mas está se recusando a atendê-lo. A autorização não ajudará e a solicitação NÃO DEVE ser repetida. Se o método de solicitação não for HEAD e o servidor desejar tornar público o motivo pelo qual a solicitação não foi atendida, DEVERÁ descrever o motivo da recusa na entidade. Se o servidor não desejar disponibilizar essas informações ao cliente, o código de status 404 (Not Found) poderá ser usado.

Isso informa ao cliente que a solicitação foi OK, mas que ela falhou (algo que um 200 não faz). Isso também lhe dá a oportunidade de explicar o problema (e sua solução) no corpo de resposta.

Quais outras condições específicas de erro você tem em mente?

Um excelente recurso para escolher o código de erro HTTP correto para sua API: http://www.codetinkerer.com/2015/12/04/choosing-an-http-status-code.html

Um trecho do artigo:

Onde começar:

insira a descrição da imagem aqui

2XX / 3XX:

insira a descrição da imagem aqui

4XX:

insira a descrição da imagem aqui

5XX:

insira a descrição da imagem aqui

A principal opção é tratar o código de status HTTP como parte de sua API REST ou não.

Ambas as formas funcionam bem. Concordo que, estritamente falando, uma das idéias do REST é que você deve usar o código de status HTTP como parte de sua API (retornar 200 ou 201 para uma operação bem-sucedida e um 4xx ou 5xx dependendo de vários casos de erro). , não há polícia REST. Você pode fazer o que você quiser. Eu tenho visto muito mais notórias APIs não-REST sendo chamadas de “RESTful”.

Neste ponto (agosto de 2015), recomendo que você use o código de status HTTP como parte de sua API. Agora é muito mais fácil ver o código de retorno ao usar estruturas do que era no passado. Em particular, agora é mais fácil ver o caso de retorno não-200 e o corpo de respostas não-200 do que era no passado.

O código de status HTTP é parte da sua API

  1. Você precisará escolher cuidadosamente os códigos 4xx que se ajustam às suas condições de erro. Você pode include uma mensagem de descanso, xml ou texto sem formatação como a carga útil que inclui um subcódigo e um comentário descritivo.

  2. Os clientes precisarão usar uma estrutura de software que permita que eles obtenham o código de status no nível HTTP. Geralmente capaz de fazer, nem sempre direto.

  3. Os clientes terão que distinguir entre códigos de status HTTP que indicam um erro de comunicação e seus próprios códigos de status que indicam um problema no nível do aplicativo.

O código de status HTTP NÃO faz parte da sua API

  1. O código de status HTTP sempre será 200 se seu aplicativo receber a solicitação e, em seguida, responder (casos de sucesso e de erro)

  2. TODAS as suas respostas devem include informações sobre “envelope” ou “header”. Tipicamente algo como:

      envelope_ver: 1.0
     status: # use os códigos que você quiser.  Reserve um código para o sucesso. 
     msg: "ok" # Uma string humana que reflete o código.  Útil para debugging.
     data: ... # Os dados da resposta, se houver. 
  3. Esse método pode ser mais fácil para os clientes, pois o status da resposta está sempre no mesmo local (não é necessário nenhum subcódigo), sem limites nos códigos, sem necessidade de buscar o código de status no nível HTTP.

Aqui está um post com uma ideia semelhante: http://yuiblog.com/blog/2008/10/15/datatable-260-part-one/

Questões principais:

  1. Certifique-se de include números de versão para poder alterar posteriormente a semântica da API, se necessário.

  2. Documento…

Lembre-se que existem mais códigos de status do que aqueles definidos nos RFCs HTTP / 1.1, o registro da IANA está em http://www.iana.org/assignments/http-status-codes . Para o caso, você mencionou que o código de status 507 está correto.

Como outros apontaram, ter uma entidade de resposta em um código de erro é perfeitamente permitido.

Lembre-se de que os erros 5xx são do lado do servidor, ou seja, o cliente não pode alterar nada em relação ao seu pedido para fazer a solicitação passar. Se a cota do cliente for excedida, isso definitivamente não é um erro do servidor, portanto, o 5xx deve ser evitado.

Eu sei que isso é extremamente tarde para a festa, mas agora, no ano de 2013, temos alguns tipos de mídia para cobrir o tratamento de erros em uma forma distribuída comum (RESTful). Veja “vnd.error”, application / vnd.error + json ( https://github.com/blongden/vnd.error ) e “Detalhes do Problema para APIs HTTP”, application / problem + json ( https: // tools. ietf.org/html/draft-nottingham-http-problem-05 ).

Existem dois tipos de erros. Erros de aplicativo e erros de HTTP. Os erros de HTTP são apenas para permitir que seu manipulador AJAX saiba que as coisas correram bem e não devem ser usadas para mais nada.

5xx Erro no servidor

 500 Internal Server Error 501 Not Implemented 502 Bad Gateway 503 Service Unavailable 504 Gateway Timeout 505 HTTP Version Not Supported 506 Variant Also Negotiates (RFC 2295 ) 507 Insufficient Storage (WebDAV) (RFC 4918 ) 509 Bandwidth Limit Exceeded (Apache bw/limited extension) 510 Not Extended (RFC 2774 ) 

Sucesso 2xx

 200 OK 201 Created 202 Accepted 203 Non-Authoritative Information (since HTTP/1.1) 204 No Content 205 Reset Content 206 Partial Content 207 Multi-Status (WebDAV) 

No entanto, a maneira como você cria os erros do seu aplicativo depende de você. O Stack Overflow, por exemplo, envia um object com propriedades de response , data e message . A resposta que acredito contém true ou false para indicar se a operação foi bem-sucedida (geralmente para operações de gravação). Os dados contêm a carga (geralmente para operações de leitura) e a mensagem contém metadados adicionais ou mensagens úteis (como mensagens de erro quando a response é false ).

Acordado. A filosofia básica do REST é usar a infraestrutura da web. Os códigos de Status HTTP são a estrutura de mensagens que permite que as partes se comuniquem entre si sem aumentar a carga HTTP. Eles já são códigos universais estabelecidos transmitindo o status de resposta e, portanto, para serem verdadeiramente RESTful, os aplicativos devem usar essa estrutura para comunicar o status da resposta.

O envio de uma resposta de erro em um envelope HTTP 200 é enganoso e força o cliente (consumidor de api) a analisar a mensagem, provavelmente de maneira não padrão ou proprietária. Isso também não é eficiente – você forçará seus clientes a analisar a carga HTTP a cada momento para entender o status de resposta “real”. Isso aumenta o processamento, adiciona latência e cria um ambiente para o cliente cometer erros.

Modelar sua API em ‘melhores práticas’ existentes pode ser o caminho a percorrer. Por exemplo, aqui está como o Twitter lida com os códigos de erro https://developer.twitter.com/en/docs/basics/response-codes

Por favor, mantenha a semântica do protocolo. Use 2xx para respostas bem-sucedidas e 4xx, 5xx para respostas a erros – sejam as exceções comerciais ou outras. Se o uso de 2xx para qualquer resposta fosse o caso de uso pretendido no protocolo, eles não teriam outros códigos de status em primeiro lugar.

Não esqueça os erros 5xx, bem como erros de aplicação.

Neste caso, e quanto ao 409 (Conflito)? Isso pressupõe que o usuário possa corrigir o problema excluindo resources armazenados.

Caso contrário, 507 (não inteiramente padrão) também pode funcionar. Eu não usaria 200 a menos que você use 200 para erros em geral.

Se a cota do cliente for excedida, é um erro do servidor, evite 5xx nesta instância.