Estou criando uma API REST, mas encontrei um problema.
Parece que a prática aceita no design de uma API REST é que, se o recurso solicitado não existir, um 404 será retornado.
No entanto, para mim, isso adiciona ambiguidade desnecessária. O HTTP 404 é mais tradicionalmente associado a um URI incorreto. Então, com efeito, estamos dizendo: "Você chegou ao lugar certo, mas esse registro específico não existe, ou não existe esse local nos Internets! Não tenho certeza de qual deles ..."
Considere o seguinte URI:
http://mywebsite/api/user/13
Se eu receber um 404 de volta, é porque o Usuário 13 não existe? Ou é porque meu URL deveria ter sido:
http://mywebsite/restapi/user/13
No passado, acabei de retornar um resultado NULL com um HTTP 200 OK
código de resposta, se o registro não existir. É simples e, na minha opinião, muito limpo, mesmo que não seja necessariamente uma prática aceita. Mas existe uma maneira melhor de fazer isso?
fonte
Respostas:
404 é apenas o código de resposta HTTP. Além disso, você pode fornecer a um corpo de resposta e / ou outros cabeçalhos uma mensagem de erro mais significativa que os desenvolvedores verão.
fonte
Use
404
se o recurso não existir. Não volte200
com o corpo vazio.Isso é semelhante a
undefined
vs string vazia (por exemplo""
) na programação. Embora muito parecido, há definitivamente uma diferença.404
significa que nada existe nesse URI (como uma variável indefinida na programação). Retornar200
com um corpo vazio significa que algo existe lá e que algo está vazio agora (como uma string vazia na programação).404
não significa que foi um "URI ruim". Existem códigos HTTP especiais destinados a erros de URI (por exemplo414 Request-URI Too Long
).fonte
String getName()
que tem uma implementação como esta:return this.name == null ? "" : this.name
. Isso não é incorreta a menos que você deseja que o cliente sabe quethis.name
énull
.Como na maioria das coisas, "depende". Mas para mim, sua prática não é ruim e não é contrária às especificações HTTP em si . No entanto, vamos esclarecer algumas coisas.
Primeiro, os URIs devem ser opacos. Mesmo que não sejam opacos para as pessoas, são opacos para as máquinas. Em outras palavras, a diferença entre
http://mywebsite/api/user/13
,http://mywebsite/restapi/user/13
é a mesma que a diferença entrehttp://mywebsite/api/user/13
e,http://mywebsite/api/user/14
portanto, não é a mesma, não é o mesmo período. Portanto, um 404 seria completamente apropriado parahttp://mywebsite/api/user/14
(se não houver esse usuário), mas não necessariamente a única resposta apropriada.Você também pode retornar uma resposta 200 vazia ou, mais explicitamente, uma resposta 204 (sem conteúdo). Isso transmitiria algo mais ao cliente. Isso implica que o recurso identificado por
http://mywebsite/api/user/14
não possui conteúdo ou é essencialmente nada. Isso significa que não é um tal recurso. No entanto, isso não significa necessariamente que você está reivindicando a existência de algum usuário em um repositório de dados com o ID 14. Essa é sua preocupação particular, não a preocupação do cliente que faz a solicitação. Portanto, se faz sentido modelar seus recursos dessa maneira, vá em frente.Existem algumas implicações de segurança em fornecer aos seus clientes informações que facilitariam a adivinhação de URIs legítimos. O retorno de 200 em caso de falha em vez de 404 pode dar ao cliente uma pista de que pelo menos a
http://mywebsite/api/user
peça está correta. Um cliente mal-intencionado pode continuar tentando números inteiros diferentes. Mas para mim, um cliente mal-intencionado seria capaz de adivinhar ahttp://mywebsite/api/user
parte de qualquer maneira. Um remédio melhor seria usar UUID's. ou seja,http://mywebsite/api/user/3dd5b770-79ea-11e1-b0c4-0800200c9a66
é melhor quehttp://mywebsite/api/user/14
. Fazendo isso, você pode usar sua técnica de retornar 200 sem revelar muito.fonte
404 Not Found tecnicamente significa que uri atualmente não mapear a um recurso. No seu exemplo, interpreto uma solicitação
http://mywebsite/api/user/13
que retorna um 404 para indicar que esse URL nunca foi mapeado para um recurso. Para o cliente, esse deve ser o fim da conversa.Para lidar com preocupações com ambiguidade, você pode aprimorar sua API fornecendo outros códigos de resposta. Por exemplo, suponha que você deseja permitir que os clientes emitam solicitações GET do URL
http://mywebsite/api/user/13
, você deseja comunicar que os clientes devem usar o URL canônicohttp://mywebsite/restapi/user/13
. Nesse caso, convém emitir um redirecionamento permanente retornando um 301 Movido permanentemente e fornecer o URL canônico no cabeçalho Localização da resposta. Isso informa ao cliente que, para solicitações futuras, ele deve usar o URL canônico.fonte
Portanto, em essência, parece que a resposta pode depender de como a solicitação é formada.
Se o recurso solicitado fizer parte do URI de acordo com uma solicitação
http://mywebsite/restapi/user/13
e o usuário 13 não existir, provavelmente um 404 é apropriado e intuitivo porque o URI é representativo de um usuário / entidade / documento / etc. O mesmohttp://mywebsite/api/user/3dd5b770-79ea-11e1-b0c4-0800200c9a66
vale para a técnica mais segura usando um GUID e o argumento api / restapi acima.No entanto, se o ID do recurso solicitado foi incluído no cabeçalho da solicitação [inclua seu próprio exemplo] ou, de fato, no URI como parâmetro, por exemplo
http://mywebsite/restapi/user/?UID=13
, o URI ainda estaria correto (porque o conceito de USER sai emhttp://mywebsite/restapi/user/
); portanto, é razoável esperar que a resposta seja 200 (com uma mensagem adequadamente detalhada) porque o usuário específico conhecido como 13 não existe, mas o URI existe. Dessa forma, estamos dizendo que o URI é bom, mas a solicitação de dados não tem conteúdo.Pessoalmente, 200 ainda não parece certo (embora eu já tenha argumentado anteriormente). Um código de resposta 200 (sem uma resposta detalhada) pode fazer com que um problema não seja investigado quando um ID incorreto é enviado, por exemplo.
Uma abordagem melhor seria enviar uma
204 - No Content
resposta. Isso é compatível com a descrição do w3c. * O servidor atendeu à solicitação, mas não precisa retornar um corpo de entidade e pode retornar informações metainformadas. * 1 A confusão, na minha opinião, é causada pela entrada da Wikipedia que indica 204 No Content - O servidor processou a solicitação com êxito, mas não está retornando nenhum conteúdo. Geralmente usado como resposta a uma solicitação de exclusão bem-sucedida .A última frase é altamente discutível. Considere a situação sem essa frase e a solução é fácil - basta enviar um 204 se a entidade não existir. Existe até um argumento para retornar 204 em vez de 404, a solicitação foi processada e nenhum conteúdo foi retornado! Esteja ciente de que os 204 não permitem conteúdo no corpo da respostaFontes
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes 1. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
fonte
Esse é um post muito antigo, mas enfrentei um problema semelhante e gostaria de compartilhar minha experiência com vocês.
Estou construindo uma arquitetura de microsserviço com APIs restantes. Eu tenho alguns serviços GET em repouso, eles coletam dados do sistema back-end com base nos parâmetros de solicitação.
Segui os demais documentos de design da API e enviei HTTP 404 com uma mensagem de erro JSON perfeita para o cliente quando não havia dados alinhados às condições da consulta (por exemplo, zero registro foi selecionado).
Quando não havia dados a serem devolvidos ao cliente, preparei uma mensagem JSON perfeita com código de erro interno etc. para informar o cliente sobre o motivo do "Não encontrado" e ele foi enviado de volta ao cliente com HTTP 404. Isso funciona bem.
Posteriormente, criei uma classe de cliente da API Rest, que é um auxiliar fácil para ocultar o código relacionado à comunicação HTTP e usei esse auxiliar o tempo todo quando chamei minhas APIs de descanso do meu código.
MAS eu precisava escrever um código extra confuso apenas porque o HTTP 404 tinha duas funções diferentes:
Importante: Meu manipulador de erros da API de descanso captura todas as exceções que aparecem no serviço de back-end, o que significa que, em caso de erro, minha API de descanso sempre retorna com uma mensagem JSON perfeita com os detalhes da mensagem.
Esta é a primeira versão do meu método auxiliar de cliente que lida com as duas respostas HTTP 404 diferentes:
MAS , porque meu cliente Java ou JavaScript pode receber dois tipos de HTTP 404 de alguma forma, preciso verificar o corpo da resposta no caso do HTTP 404. Se eu puder analisar o corpo da resposta, tenho certeza de que recebi de volta uma resposta onde havia sem dados para enviar de volta ao cliente.
Se não conseguir analisar a resposta, significa que recebi um HTTP 404 real do servidor da Web (não do aplicativo API restante).
É tão confuso e o aplicativo cliente sempre precisa fazer uma análise extra para verificar o real motivo do HTTP 404.
Honestamente, eu não gosto desta solução. É confuso, precisa adicionar código extra de besteira aos clientes o tempo todo.
Portanto, em vez de usar o HTTP 404 nesses dois cenários diferentes, decidi que faria o seguinte:
Nesse caso, o código do cliente pode ser mais elegante:
Eu acho que isso lida melhor com esse problema.
Se você tiver alguma solução melhor, compartilhe-a conosco.
fonte
Este artigo antigo, mas excelente ... http://www.infoq.com/articles/webber-rest-workflow diz isso sobre isso ...
404 Não encontrado - O serviço é muito preguiçoso (ou seguro) para nos dar uma verdadeira razão pela qual nossa solicitação falhou, mas seja qual for a razão, precisamos lidar com isso.
fonte
O identificador uniforme de recursos é um ponteiro exclusivo para o recurso. Um URI de formato incorreto não aponta para o recurso e, portanto, executar um GET nele não retornará um recurso. 404 significa que o servidor não encontrou nada correspondente ao URI da solicitação. Se você inserir o URI errado ou o URI incorreto, esse é o seu problema e o motivo pelo qual você não acessou um recurso, seja uma página HTML ou IMG.
fonte
Nesse cenário, o HTTP 404 é um código de resposta para a resposta da API REST, como entidade não processável 400, 401, 404, 422
use o tratamento de exceções para verificar a mensagem de exceção completa.
Esse bloco de exceção fornece a mensagem correta lançada pela API REST
fonte