Qual é a resposta do código de status HTTP apropriada para uma solicitação geral malsucedida (não um erro)?

109

Estou criando uma API RESTful que processará várias interações do usuário, incluindo fazer pedidos usando cartões de crédito armazenados.

No caso de um pedido bem-sucedido, estou retornando um 200 OK e, no caso de o pedido de pedido ser malformado ou inválido, estou retornando um 400 Bad Request. Mas o que devo devolver se houver um problema durante o processamento real do pedido?

  1. Cliente POSTS pedido para servidor para um recurso de usuário. Se o usuário não existir, 404 Not Found é retornado.
  2. O formato e as informações do pedido são validados. Se não for válido, 400 Bad Request é retornado.
  3. O pedido é processado. Se o pedido for bem-sucedido, um 201 Created é retornado para o pedido. Se um erro inesperado for encontrado, um 500 Server Error será retornado.

A última etapa é o problema - o que devo retornar se o pedido não for concluído por qualquer outro motivo? Os possíveis cenários podem incluir:

  • Produto esgotado
  • Limite máximo de pedido do usuário atingido
  • Falha na transação do cartão de crédito (fundos insuficientes, etc.)

Isso não parece apropriado para um 400 ou 500. Eu poderia ver como um 400 se não houvesse um código melhor - a solicitação era inválida de acordo com as regras de negócios. Simplesmente não parece preciso.

Edit: Também encontrou esta discussão existente do mesmo tópico. Todas as respostas lá parecem apontar para o uso de códigos de status para este tipo de violação, com alguma discussão entre o uso de 400, 409 ou o ramal 422.

Raelshark
fonte
8
Eu gosto de '422 entidade não processável' para erros de validação. E iria usá-lo para os exemplos acima, incluir uma mensagem na resposta com o problema de negócios real "O produto está esgotado" e possivelmente adicionar seus próprios 'códigos' se o cliente precisar tomar decisões diferentes de forma programática com base na resposta
house9 de
antes de pular para 422, considere se você
oferece

Respostas:

90

Você deve usar 400 para regras de negócios. Não devolva 2xx se a encomenda não foi aceite. HTTP é um protocolo de aplicativo, nunca se esqueça disso. Se devolver 2xx o cliente pode presumir que a encomenda foi aceite, independentemente de qualquer informação que envie no corpo.


Do RESTful Web Services Cookbook :

Um erro comum que alguns serviços da web cometem é retornar um código de status que reflete o sucesso (códigos de status de 200 a 206 e de 300 a 307), mas inclui um corpo de mensagem que descreve uma condição de erro. Isso evita que o software compatível com HTTP detecte erros. Por exemplo, um cache irá armazená-la como uma resposta bem-sucedida e servi-la aos clientes subsequentes, mesmo quando os clientes possam fazer uma solicitação bem-sucedida.

Vou deixar para você decidir entre 4xx e 5xx, mas você deve usar um código de status de erro.

Max Toro
fonte
1
Você tem exemplos ou referências para esta abordagem em relação à outra? As suas respostas e as de Widor fazem sentido, uma da perspectiva do HTTP como um protocolo de aplicativo e a outra porque é estritamente para o propósito de transferência. A especificação o define como um "protocolo de nível de aplicativo", que é um pouco vago. Também vi perspectivas e exemplos em torno da web ao pesquisar isso.
Raelshark de
isto é tão verdade.
Young Hyun Yoo de
2
Quer dizer, 'Você deve usar 4xx para regras de negócios'?
Yawar
28

Você deve usar 4xx para um erro do cliente se o cliente puder modificar a solicitação para contornar o erro. Use um 5xx para um erro de servidor que o cliente realmente não pode contornar.

Produto esgotado seria um erro do servidor. O cliente não pode modificar a solicitação de alguma forma para contornar o erro. Você poderia mudar para outro produto, mas isso não seria um novo pedido?

O limite máximo de pedido do usuário atingido também é um erro do servidor. Nada que o cliente possa fazer para contornar esse erro.

A falha na transação do cartão de crédito seria um erro do cliente. O cliente pode reenviar a solicitação com um método de pagamento ou número de cartão de crédito diferente para solucionar o erro.

Paul Morgan
fonte
6
Se o limite do pedido for atingido, o cliente não deveria alertar o usuário sobre isso e permitir que ele alterasse sua solicitação de forma adequada? Isso parece um erro 4xx. O mesmo vale para o produto que está esgotado. Os erros 5xx destinam-se a erros causados ​​pela falha do sistema de alguma forma, não a uma ação não permitida por uma regra de negócios.
carlin.scott
7
Eu concordo com o comentário acima. 5xx erros são para quando o servidor tem problemas. 4xx erros para regras de negócios.
Merc
21

Tipo de erro:

4×× Client Error

Erro de código:

422 Unprocessable Entity

O servidor entende o tipo de conteúdo da entidade de solicitação (portanto, um código de status 415 de tipo de mídia não suportado é inadequado) e a sintaxe da entidade de solicitação está correta (portanto, um código de status 400 Bad Request é inadequado), mas não foi capaz de processar o contido instruções.

Por exemplo, essa condição de erro pode ocorrer se um corpo de solicitação XML contiver instruções XML bem formadas (ou seja, sintaticamente corretas), mas semanticamente erradas.

https://httpstatuses.com/422

stamster
fonte
16

Eu sei que essa pergunta é antiga, mas eu fiz a mesma pergunta hoje. Se meu usuário ficar sem créditos, qual código de status minha API REST deve retornar?

Eu tendo a me inclinar para 402 Payment Required :

De acordo com a Wikipedia :

Reservado para uso futuro. A intenção original era que esse código pudesse ser usado como parte de alguma forma de dinheiro digital ou esquema de micropagamento, mas isso não aconteceu e esse código geralmente não é usado. A API do Google Developers usa esse status se um determinado desenvolvedor tiver excedido o limite diário de solicitações.

E de fato eles fazem :

PAYMENT_REQUIRED (402)

  • Um limite de orçamento diário definido pelo desenvolvedor foi atingido.
  • A operação solicitada requer mais recursos do que a cota permite. O pagamento é necessário para concluir a operação.
  • A operação solicitada requer algum tipo de pagamento do usuário autenticado.
Benjamin
fonte
Esta é a resposta mais bem pensada e lógica.
GTodorov
5

Que tal 424 Failed Dependency? A especificação o descreve como:

O método não pôde ser executado no recurso porque a ação solicitada dependia de outra ação e essa ação falhou.

Mas também existe esta definição :

O código de status 424 é definido no padrão WebDAV e é para um caso em que o cliente precisa alterar o que está fazendo - o servidor não está tendo nenhum problema aqui.

Você pode dizer ao cliente (ou fingir) que tem ações internas que devem criar o pedido e deduzir o saldo, e que uma dessas ações falhou, embora por motivos perfeitamente válidos, e é por isso que a solicitação falhou.

Pelo que posso ver, "ação" é um termo bastante amplo e pode ser usado em uma variedade de situações, incluindo estoque insuficiente, crédito insuficiente ou noite de festa no armazém.


Outra opção pode ser 422 Unprocessable Entity:

O servidor entende o tipo de conteúdo da entidade de solicitação (portanto, um código de status 415 de tipo de mídia não suportado é inadequado) e a sintaxe da entidade de solicitação está correta (portanto, um código de status 400 Bad Request é inadequado), mas não foi capaz de processar o contido instruções.

Por exemplo, essa condição de erro pode ocorrer se um corpo de solicitação XML contiver instruções XML bem formadas (ou seja, sintaticamente corretas), mas semanticamente erradas.

Tentar solicitar um item esgotado ou com crédito insuficiente pode ser considerado um erro semântico.

MozDev diz que isso indica um erro do lado do cliente, especificamente: O cliente não deve repetir esta solicitação sem modificação.

Loopback 4 usa 422 quando a validação de entrada falha.


Indiscutivelmente, estoque insuficiente ou noite de festa no armazém podem ser considerados estados temporários, portanto, a solicitação pode ser tentada novamente mais tarde. Essa situação pode ser indicada por503 Service Unavailable

No momento, o servidor não pode atender à solicitação devido a uma sobrecarga temporária ou manutenção programada, que provavelmente será aliviada após algum atraso.

O servidor PODE enviar um campo de cabeçalho Retry-After para sugerir um período de tempo apropriado para o cliente esperar antes de tentar novamente a solicitação.

joeytwiddle
fonte
Nenhum deles está relacionado a um pagamento. Vou com 402 da resposta anterior!
GTodorov
2

Eu não acho que 400 pode ser usado para todo o cenário de negócios. Ele pode ser usado para validação de entrada de dados básicos. Além disso, talvez seja difícil encaixar outra lógica de negócios nesse código de erro. Os erros tratados por isso são principalmente erros de tempo de design que o desenvolvedor encontrará possivelmente durante a codificação do cliente.

Digamos que todos os parâmetros estejam corretos e que estejamos passando o número da conta do usuário para a solicitação.

Portanto, a solicitação agora não é mais uma solicitação incorreta, o servidor pode aceitar a solicitação. Mas agora se recusa a preencher o pedido com base nas novas informações disponíveis, que é - a conta não tem saldo suficiente.

Eu sugeriria que devemos usar 403 com a mensagem de erro apropriada nesses cenários.

Outro código de erro possível pode ser o conflito 409. Mas isso é usado em cenários onde o recurso está em estado consistente.

Rajender Saini
fonte
-1

Eu vou com 406 Not Acceptable.

Aqui está uma lista 4xx:

const HTTP_BAD_REQUEST = 400;
const HTTP_UNAUTHORIZED = 401;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_FORBIDDEN = 403;
const HTTP_NOT_FOUND = 404;
const HTTP_METHOD_NOT_ALLOWED = 405;
const HTTP_NOT_ACCEPTABLE = 406;
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
const HTTP_REQUEST_TIMEOUT = 408;
const HTTP_CONFLICT = 409;
const HTTP_GONE = 410;
const HTTP_LENGTH_REQUIRED = 411;
const HTTP_PRECONDITION_FAILED = 412;
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
const HTTP_REQUEST_URI_TOO_LONG = 414;
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
const HTTP_EXPECTATION_FAILED = 417;
const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
const HTTP_MISDIRECTED_REQUEST = 421;                                         // RFC7540
const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
const HTTP_LOCKED = 423;                                                      // RFC4918
const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585
Mahmoud Zalt
fonte
8
Embora o nome do código de status 406 possa soar preciso por si só, você precisa estar ciente de que cada código de status tem uma descrição textual autorizada. A descrição do código de status 406 não é adequada para o caso em questão. Consulte httpstatuses.com/406 , por exemplo.
Zero3
1
@ Zero3 está certo, este código significa que o tipo de resposta não é aceitável, pois há uma incompatibilidade entre os cabeçalhos de aceitação enviados do cliente e os MediaType (s) enviados pelo endpoint, por exemplo, aplicativo / json vs. texto / simples
Gregor