Devo usar códigos de status HTTP para descrever eventos no nível do aplicativo

48

Vários servidores com os quais lidei retornarão o HTTP 200 para solicitações que o cliente deveria considerar uma falha, com algo como 'success: false' no corpo.

Isso não parece uma implementação adequada de códigos HTTP para mim, especialmente em casos de falha na autenticação. Li códigos de erro HTTP resumidos de maneira bastante sucinta, pois '4xx' indica que a solicitação não deve ser feita novamente até ser alterada, enquanto '5xx' indica que a solicitação pode ou não ser válida e pode ser repetida, mas sem êxito. Neste caso, 200: login falhou, ou 200: não conseguiu encontrar o arquivo, ou 200: faltando o parâmetro x, definitivamente parece errado.

Por outro lado, eu pude ver o argumento sendo feito de que '4xx' deveria apenas indicar um problema estrutural com o pedido. Então, isso é apropriado para retornar 200: usuário / senha inválido em vez de 401 não autorizado porque o cliente tem permissão para fazer a solicitação, mas acontece de estar incorreto. Esse argumento poderia ser resumido como, se o servidor foi capaz de processar a solicitação e fazer uma determinação, o código de resposta deve ser 200, e cabe ao cliente verificar o corpo para obter mais informações.

Basicamente, isso parece ser uma questão de preferência. Mas isso é insatisfatório, então se alguém tem uma razão pela qual um desses paradigmas é mais correto, eu gostaria de saber.

    
por Kagan Mattson 16.12.2015 / 19:11
fonte

3 respostas

32

Pergunta interessante.

Basicamente, podemos reduzir isso para o caminho certo para classificar as coisas em termos análogos às camadas OSI. O HTTP é comumente definido como um protocolo de nível de aplicativo, e o HTTP é de fato um protocolo genérico de cliente / servidor.

No entanto, na prática, o servidor é quase sempre um dispositivo de retransmissão, e o cliente é um navegador da Web, responsável por interpretar e renderizar conteúdo: o servidor apenas passa as informações para um aplicativo arbitrário e esses aplicativos enviam de volta scripts arbitrários qual o navegador é responsável pela execução. A interação HTTP em si - os formulários de solicitação / resposta, os códigos de status e assim por diante - é principalmente uma questão de como solicitar, exibir e renderizar conteúdo arbitrário da maneira mais eficiente possível, sem atrapalhar. Muitos dos códigos de status e cabeçalhos são realmente projetados para esses propósitos.

O problema de tentar utilizar o protocolo HTTP para lidar com fluxos específicos de aplicativos é que você tem uma de duas opções: 1) Você deve tornar sua lógica de solicitação / resposta um subconjunto das regras HTTP; ou 2) Você deve reutilizar certas regras e, em seguida, a separação de interesses tende a ficar confusa. Isso pode parecer bom e limpo no começo, mas acho que é uma daquelas decisões de design que você acaba lamentando à medida que seu projeto evolui.

Portanto, eu diria que é melhor ser explícito sobre a separação de protocolos. Deixe o servidor HTTP e o navegador da Web fazerem as suas próprias coisas, e deixe o aplicativo fazer o próprio seu . O aplicativo precisa ser capaz de fazer solicitações e precisa das respostas - e sua lógica de como solicitar, como interpretar as respostas, pode ser mais (ou menos) complexa do que a perspectiva HTTP.

O outro benefício dessa abordagem, que vale a pena mencionar, é que os aplicativos, em geral, não devem depender de um protocolo de transporte subjacente (do ponto de vista lógico). O próprio HTTP foi alterado no passado e agora temos o HTTP 2 funcionando, seguindo o SPDY. Se você visualizar seu aplicativo como não mais do que um plug-in de funcionalidade HTTP, poderá ficar preso quando novas infraestruturas forem implementadas.

    
por 17.12.2015 / 10:31
fonte
21

Esta questão é um pouco baseada em opiniões, mas de qualquer forma.

Do jeito que eu vejo, 200 pode servir "erros de software". Quando se trata de criar APIs, tento distinguir entre esses e "erros difíceis".

"Erros de software" será exibido com um código de status de 200, mas conterá uma descrição de erro e um status de sucesso de false . "Soft errors" só ocorrerá quando o resultado for "como esperado", mas não será um sucesso no sentido mais estrito.

É importante notar que "erros de software" são mais uma sugestão para o implementador. Portanto, é importante também fornecer mais informações sobre o erro, como uma mensagem de erro legível e / ou algum tipo de código que possa ser usado para fornecer feedback ao usuário final. Esses erros fornecem ao implementador (e ao usuário final) mais informações sobre o que aconteceu no lado do servidor das coisas.

Por exemplo, digamos que você tenha uma API com uma função de pesquisa, mas durante uma pesquisa, nenhum resultado é gerado. Isso não é errado, mas também não é um "sucesso", não no sentido estrito da definição.

Exemplo formatado como JSON:

{
    "meta" {
        "success": false,
        "message": "Search yielded no results",
        "code": "NORESULTS"
    }
    "data": []
}
"Hard errors" , por outro lado, será exibido com um código de status recomendado para o erro. Usuário não está logado? - 403 / 401. Entrada mal formada? - 400. Erro no servidor? - 50X E assim por diante.

Novamente, é um pouco baseado em opinião. Algumas pessoas querem tratar todos os erros igualmente, "erro duro" tudo. Nenhum resultado de pesquisa? Isso é um 404! Do outro lado da moeda, não há resultados de pesquisa? - Isso é o esperado, sem erros.

Outro fator importante a considerar é a sua arquitetura, por exemplo; se você interagir com sua API usando solicitações de JavaScript XHR e jQuery ou AngularJS. Esses "erros físicos" terão que ser tratados com um retorno de chamada separado, enquanto os "erros de software" podem ser manipulados com o retorno "de sucesso". Não quebrando nada, o resultado ainda é "como esperado". O código do lado do cliente pode então olhar para o status de sucesso e código (ou mensagem). E imprima isso para o usuário final.

    
por 16.12.2015 / 20:18
fonte
13

Existem dois aspectos de uma API: o esforço para implementar a API e o esforço de todos os clientes para usar a API corretamente.

Como autor do cliente, sei que, quando envio uma solicitação a um servidor da Web, posso obter um erro (nunca falei corretamente com o servidor) ou uma resposta com um código de status. Eu tenho que lidar com os erros. Eu tenho que lidar com uma boa resposta. Eu tenho que lidar com respostas esperadas, documentadas e "ruins". Eu tenho que lidar com o que mais voltar.

Projetando a API, você deve verificar o que é mais fácil para o cliente processar. Se o cliente enviar uma solicitação bem formada, e você puder fazer o que a solicitação lhe pede, então você deve dar uma resposta no intervalo de 200 (há alguns casos em que um número diferente de 200 nesse intervalo é apropriado).

Se o cliente perguntar "me dê todos os registros como ...", e houver zero, então um 200 com sucesso e uma matriz de zero registros é totalmente apropriado. Os casos que você mencionou:

"Login failed" geralmente deve ser um 401. "Não foi possível encontrar o arquivo" deve ser um 404. "Parâmetro inexistente x" deve ser algo em torno de 500 (na verdade, um 400 se o servidor descobrir que a solicitação é ruim e 500 se o servidor estiver totalmente confuso com o meu pedido e não tiver ideia do que está acontecendo). Retornar 200 nesses casos é inútil. Significa apenas como o autor de um cliente, não posso apenas olhar para o código de status, tenho que estudar a resposta também. Não posso simplesmente dizer "status 200, ótimo, aqui estão os dados".

Especialmente o "parâmetro ausente" - isso não é algo que eu jamais manipulei . Isso significa que meu pedido está incorreto. Se minha solicitação estiver incorreta, não tenho um substituto para corrigir essa solicitação incorreta - enviaria uma solicitação correta para começar. Agora sou forçado a lidar com isso. Eu recebo um 200 e tenho que verificar se há uma resposta "parâmetro ausente". Isso é horrível.

No final, há uma dúzia ou dois códigos de status para lidar com muitas situações diferentes e você deve usá-los.

    
por 16.12.2015 / 22:45
fonte