Digamos que eu tenho um ponto de extremidade REST que usa um número inteiro como parâmetro:
/makeWaffles?numberOfWaffles=3
Nesse caso, quero que o número seja positivo, porque não posso fazer um número negativo de waffles (e solicitar 0 waffles é uma perda de tempo). Então, eu quero rejeitar qualquer solicitação que não contenha um número inteiro positivo. Também quero rejeitar uma solicitação que exceda um número inteiro máximo (digamos que agora seja MAX_INTEGER).
No caso de alguém solicitar um número não positivo de waffles, devo retornar um status HTTP 400 (Solicitação incorreta)? Meu pensamento inicial é sim: não é um número válido para mim concluir a solicitação. No entanto, o RFC não menciona regras de negócios como um motivo para lançá-lo:
O código de status 400 (Solicitação incorreta) indica que o servidor não pode ou não processará a solicitação devido a algo que é percebido como um erro do cliente (por exemplo, sintaxe de solicitação malformada, enquadramento de mensagem de solicitação inválida ou roteamento de solicitação enganoso).
Uma regra de negócios não se enquadra em nenhum desses três exemplos. É sintaticamente correto, está emoldurado corretamente e não é um roteamento de solicitação enganoso.
Portanto, devo retornar um status HTTP 400 (Solicitação incorreta) se um parâmetro estiver sintaticamente correto, mas violar uma regra de negócios? Ou existe um status mais apropriado para retornar?
fonte
Respostas:
Essa é uma ótima pergunta, e ainda altamente relevante, dado o contexto histórico (e as definições aparentemente contraditórias) dos códigos de retorno HTTP. Mesmo entre as respostas a esta pergunta há definições conflitantes. Isso pode ser esclarecido movendo-se cronologicamente.
RFC 2616 (junho de 1999)
A partir deste RFC, esse código de status aplicava-se especificamente apenas a solicitações sintaticamente inválidas. Houve uma lacuna nos códigos de status para validação semântica. Assim, quando a RFC 4918 apareceu, um novo código nasceu.
RFC 4918 (junho de 2007)
422 Entidade não processável foi criada para preencher a lacuna da validação semântica na especificação original dos códigos de status 4xx. No entanto, outra RFC relevante surgiu em 2014, que generalizou 400 para não ser mais específica à sintaxe .
RFC 7231 (junho de 2014, obsoleta explicitamente a RFC 2616)
Observe que a descrição 422 diz que o motivo 400 é inapropriado porque 400 (a partir da RFC 2616) deve ser retornado apenas para sintaxe de solicitação incorreta. No entanto, a partir da RFC 7231, a definição estrita de erro de sintaxe não se aplica mais a 400 .
Voltando à pergunta em questão: Embora o 422 seja tecnicamente mais específico, nesse contexto, pude ver 400 ou 422 sendo usados para validação semântica dos parâmetros da API. Eu hesito em usar 422 em minhas próprias APIs porque a definição de 422 está tecnicamente desatualizada neste momento (embora eu não saiba se isso é oficialmente reconhecido em qualquer lugar). O artigo mencionado na resposta de Fran, que incentiva o uso do 422, foi escrito em 2012, dois anos antes da RFC 7231 esclarecer o HTTP 400. Certifique-se de padronizar um ou outro.
fonte
Eu li a primeira resposta e realmente não concordo com isso porque, pelo menos na minha leitura, uma solicitação ruim (400) significa: "Eu não posso nem lidar com sua solicitação porque algo está fundamentalmente errado". E eu encontrei este post que justifica o retorno de um 422.
da IETF
422 Entidade não processável (WebDAV; RFC 4918) A solicitação foi bem formada, mas não pôde ser seguida devido a erros semânticos
Parece uma resposta mais apropriada, pois sua solicitação é bem-formada, mas não passa nas regras de validação.
fonte
Não você não deveria. Os códigos HTTP destinam-se à camada HTTP do seu aplicativo. As regras de negócios têm uma camada completamente diferente e são específicas do aplicativo, portanto, você precisa criar seu próprio "protocolo".
Imagine um apocalipse e você precisa mudar do protocolo HTTP para usar o Pigeons. Os pombos não têm códigos de retorno, portanto, você precisará alterar sua camada de negócios para acomodar isso. Mas sua empresa realmente não mudou de forma alguma, portanto você não precisa alterar a camada de negócios. Ele mostra um forte acoplamento entre essas duas camadas (transporte e negócios).
Voltar à pergunta: O que você deve fazer é retornar "200 OK" com um corpo que descreva o que aconteceu com a solicitação. A especificação diz claramente isso:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .
Sua solicitação HTTP foi bem-sucedida? Sim, o servidor da web sabe o que fazer com essa solicitação (por exemplo, repasse para a parte do servidor do seu aplicativo). O servidor da Web passa essa solicitação para a parte do servidor do seu aplicativo, que recebe os dados POST, os processa (os valida no seu caso) e retorna uma resposta normal (no corpo de uma resposta HTTP) para a parte do cliente do seu aplicativo . Esta resposta da parte do servidor do aplicativo pode ser "Ótimo, os dados que você me enviou são válidos" ou "Sinto muito, os dados que você enviou não são válidos". E cabe ao seu cliente parte do aplicativo entender o que significa a resposta.
PS: "400 Solicitação incorreta" significa que o servidor da Web não entendeu o que você deseja dele. Isso significa que a parte do servidor do seu aplicativo nem sequer recebeu a solicitação. Ou pelo menos é isso que significa :-)
EDIT : Acabei de perceber, que você está fazendo solicitação GET, não POST. Essa é uma péssima idéia, pois GET não deve alterar o estado do aplicativo. GET deve simplesmente recuperar dados do servidor. Mas, na sua solicitação, você está realmente alterando o estado do aplicativo, portanto, você deve realmente usar o POST.
fonte
Sim, a entrada que não segue o contrato implícito do nó de extremidade é "algo percebido como um erro do cliente" e deve retornar 400.
As exceções são se a regra de negócios estiver relacionada à segurança (então
401 Unauthorized
ou403 Forbidden
seria melhor). Como alternativa, se enviar um 400 vazasse informações sobre a existência de algo e, em seguida, a404 Not Found
poderá ser mais apropriado.fonte
Não temos certeza de que todos concordariam, mas estamos usando o 409 - Conflict. Muitos afirmam que o 409 é mais um conflito com o estado do sistema, mas aceitamos a interpretação de que um conflito de valores de dados fora do intervalo aceito é corrigível pelo solicitante e um uso aceitável de 409. 422 Eu acho que seria razoável conforme a solicitação está formado corretamente, mas não pode ser processado conforme solicitado. Opino no entanto, se você não deseja implementar uma série de respostas, apenas dar 400 ainda é aceitável.
fonte