Os códigos de status HTTP devem ser usados ​​para representar erros de lógica de negócios em um servidor?


20

Estou numa encruzilhada com algum design de API para um cliente (JS em um navegador) conversar com um servidor. Usamos o Conflito HTTP 409 para representar a falha de uma ação devido a um bloqueio de segurança em vigor. O bloqueio satisfatório impede que os desenvolvedores façam alterações acidentalmente nos sistemas de produção de nossos clientes. Fui encarregado de lidar com os 409 um pouco mais graciosamente no cliente para indicar por que uma chamada de API específica falhou.

Minha solução foi agrupar os manipuladores de falhas de qualquer uma de nossas chamadas AJAX, que exibirão uma notificação no cliente quando algo falhar devido ao 409 - tudo está bem e funciona bem ao lado de outros erros 4XX e 5XX que usam o mesmo mecanismo.

Surgiu um problema em que um de nossos manipuladores de rota responde com 409s ao encontrar um erro de lógica de negócios - meu wrapper AJAX relata que a trava de segurança está ativada, enquanto o manipulador de falhas existente do cliente relata o que (pensa) o problema é baseado no corpo da resposta. Uma solução simples seria alterar a resposta do manipulador ou o código de status que usamos para representar a trava de segurança.

O que me leva à minha encruzilhada: os códigos de status HTTP devem ser usados ​​para representar erros de lógica de negócios? Esta pergunta aborda o mesmo problema que estou enfrentando, mas não ganhou muita força. Conforme sugerido na resposta vinculada, estou inclinado a usar o HTTP 200 OK com um corpo apropriado para representar falha na lógica de negócios.

Alguém tem alguma opinião forte aqui? Alguém é capaz de me convencer de que esta é a maneira errada de representar o fracasso?


3
Hesito em postar minha opinião simples como resposta. Em resumo: geralmente evito usar códigos de status HTTP para representar erros de negócios. Eles devem pertencer apenas ao status da comunicação entre cliente e servidor. Um código de status adequado para retornar erros de validação ou lógica de negócios seria 400 Bad Request. O motivo dessa separação é que os sistemas, desenvolvedores ou leitores de documentos futuros podem ficar confusos com o desvio do padrão mundial.
Ivo Coumans

@IvoCoumans: faça desta ^ uma resposta para que eu possa votar novamente. 400 Bad Requestcomo um código HTTP geral parece melhor cobrir erros de lógica de negócios como uma classe.
9000

Preferência pessoal, mas costumo usar 400 Bad Requestquando faltam dados ou não podem ser lidos / analisados. Ou seja, os dados da solicitação em si são ruins de alguma forma.
Kasey Speakman

Expanda o que você entende por "erro de lógica de negócios". Isso é extremamente vago. Você quer dizer entrada inválida de acordo com as verificações (corretas) de validação de dados, entrada que pode ser válida em algum outro momento, mas inválida no estado atual ou um erro na lógica de negócios em que está rejeitando uma entrada válida?
precisa saber é o seguinte

@ jpmc26 Eu estava sendo intencionalmente vago, pois era uma pergunta geral. Os servidores lidaram bem com a solicitação, mas decidiram que a consulta / afirmação não fazia sentido.
Joe Shanahan 26/09

Respostas:


19

Kasey cobre o ponto principal.

A idéia principal em qualquer API da Web: você está adaptando seu domínio para se parecer com um repositório de documentos. GET / PUT / POST / DELETE e assim por diante são todas as formas de interagir com o armazenamento de documentos.

Portanto, uma maneira de pensar sobre quais códigos usar é entender como é a operação análoga em um repositório de documentos e como essa falha seria nesse analógico.

2xx é completamente inadequado

A classe 2xx (Bem-sucedida) do código de status indica que a solicitação do cliente foi recebida, entendida e aceita com êxito.

5xx também não é adequado

A classe 5xx (Erro do servidor) do código de status indica que o servidor está ciente de que errou

Nesse caso, o servidor não cometeu um erro; está ciente de que você não deve modificar esse recurso dessa maneira no momento.

Os erros de lógica de negócios (o que significa que a invariante de negócios não permite a edição proposta no momento) provavelmente são 409

O código de status 409 (Conflito) indica que a solicitação não pôde ser concluída devido a um conflito com o estado atual do recurso de destino. Esse código é usado em situações em que o usuário pode resolver o conflito e reenviar a solicitação. O servidor DEVE gerar uma carga útil que inclua informações suficientes para que um usuário reconheça a fonte do conflito.

Observe este último bit - a carga útil da resposta 409 deve estar comunicando informações ao consumidor sobre o que deu errado e, idealmente, inclui controles hipermídia que levam o consumidor aos recursos que podem ajudar a resolver o conflito.

Minha solução foi agrupar os manipuladores de falhas de qualquer uma de nossas chamadas AJAX, que exibirão uma notificação no cliente quando algo falhar devido ao 409 - tudo está bem e funciona bem ao lado de outros erros 4XX e 5XX que usam o mesmo mecanismo.

E eu apontaria isso como o problema; sua implementação no cliente assumiu que o código de status era suficiente para definir o problema. Em vez disso, seu código de cliente deve revisar a carga útil e agir de acordo com as informações disponíveis lá.

Afinal, é assim que um repositório de documentos faria isso

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

A mesma abordagem com a 400 Bad Requesttambém seria aceitável; que aproximadamente "se traduz em" Ocorreu um problema com sua solicitação. Não podemos nos incomodar em descobrir qual código de status é o mais adequado. Então, aqui está. Veja a carga útil para obter detalhes. "

Eu usaria 422. A entrada é válida, portanto 400 não é o código de erro correto a ser usado

A especificação WebDAV inclui esta recomendação

O código de status 422 (Entidade não processável) significa que o servidor entende o tipo de conteúdo da entidade solicitada (portanto, um código de status 415 (Tipo de mídia não suportado) é inadequado) e a sintaxe da entidade solicitada está correta (portanto, 400 (Solicitação incorreta) ) código de status é inapropriado), mas não conseguiu processar as instruções contidas. 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.

Eu não acredito que seja uma partida (embora eu concorde que ela lança alguma dúvida 400como alternativa). Minha interpretação é que 422significa "você enviou a entidade errada", onde 409está "você enviou a entidade na hora errada".

Em outras palavras, 422indica um problema com a mensagem de solicitação considerada isoladamente, em 409que indica que a mensagem de solicitação entra em conflito com o estado atual do recurso.

A discussão de Ben Nadal sobre 422 pode ser útil considerar.


5
" você está adaptando seu domínio para se parecer com um repositório de documentos " - eu adoraria ver as pessoas lendo isso e entender completamente todas as conseqüências e implicações antes de decidirem a favor ou contra o REST. Realmente.
JensG

"Erros de lógica de negócios" parece "entrada inválida" para mim, que geralmente é normalmente um número 400, pois não há um código de erro mais específico para ele. Se não for a entrada inválida, o servidor possui um erro e 500 é apropriado. Sua resposta parece assumir muito sobre a natureza de um "erro de lógica de negócios".
precisa saber é o seguinte

Eu usaria 422. A entrada é válida, portanto 400 não é o código de erro correto a ser usado
Konrad

19

Na minha experiência, os códigos de erro HTTP são insuficientes para representar erros de negócios. No entanto, eles são úteis para representar classes de erros.

Portanto, minha recomendação seria usar códigos de erro HTTP para categorias de erros, mas escolha um erro específico para falhas de lógica de negócios (por exemplo, 409 Conflito ... 200 OK seria enganoso aqui) e inclua dados na resposta indicando o erro de negócios específico . Verifique se isso faz parte do conteúdo da resposta e não do texto de status, porque alguns navegadores ignoram o texto de status personalizado. O idioma que eu gosto de usar tem tipos de união que são convenientes para representar mensagens. Mas você também pode definir constantes de cadeia para casos de erro.

Exemplos

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }

Os códigos de status 4xx acima de 400 têm significados muito específicos. Escolha 400 se o seu caso não for coberto especificamente pelos outros.
precisa saber é o seguinte

@ jpmc26 Se eu não usar os códigos de status dessa maneira, eles nunca serão usados. Mas fique à vontade para usá-los da maneira certa e correta em suas respostas.
Kasey Speakman

Em certo sentido, você está certo. Eles nunca são usados. Os significados escolhidos para os códigos específicos não parecem ser casos de uso muito comuns para a maioria dos aplicativos. Tudo bem. Existem muitas exceções que nunca escrevemos código para capturar.
precisa saber é o seguinte

@ jpmc26 Bem, as exceções não são o melhor modelo a seguir . Mas claro, vá em frente.
Kasey Speakman

Não lançar ou capturar tipos de exceção específicos é o análogo de nunca usar códigos HTTP específicos ou quaisquer outros códigos de erro. Eu assumi que isso seria óbvio. Se um modelo de exceção é "o melhor" é totalmente irrelevante ao ponto.
Jpmc26 26/09/19

5

Geralmente, evitava usar códigos de status HTTP para representar erros específicos da lógica de negócios. Isso ocorre porque eles já têm um significado semântico definido pelo padrão mundial. Outros sistemas, novos desenvolvedores e assim por diante serão confundidos pelo seu desvio do padrão.

O que descobri em pesquisas recentes e similares foi que geralmente é aceito o uso 400 Bad Requestem caso de erros de validação e outros. Dessa forma, você usa um código de status para todos os erros de lógica de negócios.

Aliás, 409deve ser usado quando um recurso foi alterado enquanto você o estava editando e tentou salvá-lo novamente.


4

Você pode usar "Solicitação incorreta" e incluir o ID da regra de negócios violada, além de mais alguns detalhes no corpo da resposta.


Eu não sei qual foi o voto negativo. É assim que as empresas podem retornar exceções de negócios.
Skadoosh 27/09/18
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.