"Sem resultados" deve ser um erro em uma resposta RESTful?


52

Vou descrever um exemplo:
começo a fazer uma API para uma padaria. A API permitirá que as pessoas pesquisem em seu catálogo produtos de panificação, como biscoitos caseiros com pedaços de chocolate api.examplebakery.com/search?q=......

Alguém usa isso para procurar um produto nomeado pineapple-banana flavoured cookiese obviamente não encontrará nenhum resultado.

Isso deve ser retornado como um erro? A pesquisa não falhou, a API pesquisou e concluiu com êxito que nenhum cookie foi encontrado. A API não deve retornar 404, porque a API foi realmente encontrada.




3
@gnat: Esta não é uma duplicata, porque a outra pergunta é sobre um recurso específico, não uma consulta contra vários recursos.
Greg Burghardt

7
Analogamente, suponha que você tenha uma função que retorne uma matriz de objetos. Se não houver objetos que correspondam a um caso de uso específico, você prefere a função através de uma exceção ou retorna uma matriz vazia?
Kevin - Restabelece Monica

2
@AakashM O retorno do HTTP-204 a uma solicitação GET é bastante incomum, eu sei que não vi isso em lugar nenhum. Até onde eu sei, o HTTP-204 geralmente é usado como resposta ao modificar um recurso no servidor, por exemplo, solicitações POST / PUT / DELETE.
Radu Murzea 28/09

Respostas:


122

Quando há resultados, a saída é uma lista (JSON, com base no seu comentário). Para consultas sem resultados, a saída deve ser exatamente a mesma. A lista simple possui 0 itens.

Portanto, se sua resposta é normalmente esta:

{
    "results": [
        {
            "name": "Pancakes",
            ....
        },
        {
            "name": "French Fries",
            ....
        }
    ]
}

Então, para uma consulta com 0 resultados, deve ser o seguinte:

{
    "results": []
}

Se você também incluir metadados sobre quantas "páginas" de resultados existem, links para essas "páginas" etc. etc., sugiro dizer que existe uma "página".

O status HTTP deve ser o mesmo de quando houver resultados - 200 OK.

204 No Contenttambém pode parecer uma opção, mas não é porque você está retornando "conteúdo" - a lista vazia. Se você acha que uma lista vazia não conta como "conteúdo", e se você alterar a resposta para oferecer sugestões de ortografia? O núcleo da resposta ainda será uma lista vazia, mas agora há ainda mais "conteúdo".

Para obter informações mais úteis sobre códigos de status HTTP, jpmc26 vale a pena ler sua resposta .


9
Esse é o mesmo tipo de pensamento que o padrão de objeto nulo . Erros e nulo não são a única maneira de dizer que não há nada aqui. Às vezes você quer expressar seu nada em silêncio. Dessa forma, os clientes não precisam testar por nada.
Candied_orange 28/09

54
Eu diria que retornar um 204 é inadequado, pois você está retornando conteúdo. Só que o conteúdo não tem resultados, o que é diferente de não retornar nenhum conteúdo.
TMN

9
@TMN concordou - 204 não é apropriado para "nenhum resultado". Sua consulta sempre deve retornar uma matriz, com os resultados dentro da matriz. Se não houver resultados, o cliente cuidará disso naturalmente. Se o cliente quiser mostrar texto especial ("Nenhum resultado foi encontrado"), tudo bem. 204 só deve ser retornado para um terminal que não retorna naturalmente um resultado.
JasonB

11
Você poderia usar 204 se estivesse retornando null serializado como um reconhecimento vazio corda I
Ewan

15
Este. O importante na construção de uma API RESTful é a parte da API, não a tranqüilidade. Uma boa API facilita a vida dos clientes / consumidores. Uma matriz vazia é mais fácil de manipular do que valores nulos / exceções / códigos de status.
Guran

37

Ao decidir sobre um código HTTP, você deve sempre fazer esta pergunta:

O que um cliente arbitrário pode / fará / deve fazer com a resposta?

  1. O cliente deve sempre tratar a resposta como uma falha? Você deseja 4xx ou 5xx, dependendo se o problema é a entrada do cliente ou os processos do servidor.
  2. O cliente deve fazer uma solicitação em outro lugar? Então 3xx é para você.
  3. O servidor fez o que o cliente pediu (foi bem-sucedido)? Isso é 2xx.

Sempre decida em qual intervalo seu código de resposta deve estar primeiro. Fazer isso rapidamente elimina muitos códigos de resposta como opções e (talvez mais importante) torna muito mais simples seguir a semântica dos códigos. Consulte as seções iniciais da documentação do código HTTP para obter explicações sobre o que cada categoria de código representa.

Nesse caso, o cliente solicitou uma lista de resultados com um filtro de um terminal válido existente e tem autorização para acessá-lo. O servidor conseguiu processar a solicitação e determinar os dados apropriados a serem retornados (sem itens), portanto, a solicitação foi bem-sucedida. Acontece que o filtro que eles forneceram filtrou todos os resultados. Não cabe ao servidor determinar se é isso que o cliente deseja ou não, pois esse pode ser um resultado esperado para alguns clientes. Se, de alguma forma, for um problema para o código do cliente, essa é a responsabilidade do cliente determinar, verificar e manipular adequadamente. Então isso é claramente 2xx.

Agora, a pergunta é: "Qual 2xx?" Isso depende de como você pretende que o servidor responda.

  • Você enviará de volta uma representação de uma lista vazia, como algumas outras respostas descrevem? Nesse caso, você deseja 200. 200 significa que o servidor não teve problemas e tem uma representação dos resultados para o cliente consumir. Essa é provavelmente a maneira mais conveniente de responder por seus consumidores, que podem analisar a resposta, independentemente de haver resultados ou não, e depois descobrir como lidar com uma lista vazia.
  • O artigo 204 não está semanticamente errado aqui, mas você teria que responder sem o corpo da mensagem . Isso significa que todo o código do cliente precisaria verificar explicitamente códigos HTTP diferentes (ou pelo menos a falta de um corpo da mensagem) e manipulá-los separadamente. É inconveniente e mais propenso a levar a clientes mal comportados.

Os outros não são aplicáveis:

  • 201 está fora de questão. Você não criou recursos persistentes e não está retornando um local para um recurso criado.
  • 202 está fora de questão. O pedido está feito; não está processando em segundo plano.
  • 203 significa que a resposta foi modificada entre o servidor autoritário e o cliente. Sua interface RESTful é o servidor autoritativo, portanto, isso não se aplica aqui.
  • 205 não faz sentido. Você não precisa que o cliente limpe ou atualize nada.
  • 206 parece ter sido projetado para retornar um grande recurso em várias respostas. Também requer que o cliente solicite uma parte do conteúdo nos cabeçalhos (para que a paginação por cadeias de consulta não se qualifique). Não aplicável aqui.

Portanto, deve ser 200 ou 204, e é mais provável que 200 leve a um código de cliente mais simples e robusto (especialmente se você usar uma estrutura de resposta consistente contendo uma lista vazia).


5
Estaria interessado na opinião do voto negativo. Eu não acho que nada disso seja controverso.
precisa saber é o seguinte

2
Não acho que os clientes tenham que procurar 204 explicitamente. Tudo o que eles precisam é a capacidade de lidar com objetos de resposta nula. O trabalho da estrutura HTTP é lidar com 204 ignorando a parte "analisar o corpo". 200 com Conteúdo-Comprimento 4 e corpo nulo são iguais.
Agent_L

11
@Agent_L Você está certo que, se o servidor responder com uma estrutura inconsistente com a resposta normal (como colocar nullonde normalmente há uma lista), você não colherá os benefícios da consistência mesmo com o 200. No entanto, o que eu descrevo é usar um resposta que seja consistente com a estrutura normal e tenha uma lista vazia para onde a lista de resultados normalmente iria. 204 tira qualquer oportunidade de ter uma resposta tão consistente. Além disso, mesmo nas bibliotecas de clientes HTTP que possuem funções convenientes, geralmente (normalmente?) É necessário fazer uma chamada explícita para analisar o JSON.
Jpmc26 29/09/2015

@Agent_L Em particular nas listas, os chamadores geralmente deixam o código rodar normalmente em uma lista vazia (fazendo um loop sobre ele, por exemplo), enquanto eles precisariam de uma verificação explícita de algum tipo para lidar com outro tipo de representação.
Jpmc26

16

Não. O uso de 404 para indicar 'sua consulta foi processada, mas não houve correspondências' é péssimo porque:

  • fluxo condicional com base no tratamento de exceções (ou seja, forçar um resultado não excepcional a criar e manipular uma exceção no cliente que pode não ter desempenho e ser desajeitada)

  • ambiguidade entre a página 'real' não encontrada, você digitou erros errados no terminal

O que deve ser lembrado é que sempre há um cliente para desserializar a mensagem e o que esse cliente retorna é importante; não a serialização.

Se o cliente retornar nulo, use a serialização de nulo. Se o cliente retornar uma matriz vazia, use []; se o cliente gerar um erro, use 500 e passe a mensagem de erro


2
Por que o servidor deve se importar com o que o cliente está fazendo com as informações? (PS: Não fui eu quem rebaixou sua resposta).
Radu Murzea 28/09

Nesse contexto, o 'cliente' é o código em execução no dispositivo cliente que expõe o serviço ao aplicativo cliente. Ele deve poder expor os métodos de serviços e retornar os resultados conforme pretendido pelo serviço. Você precisa de um par cliente-servidor para a comunicação à função em tudo
Ewan

3
Não use 5xx para erros de clientes , é claro. Prefira 4xx nesse caso.
Kevin

11
Embora não deva ser "servidor", não "cliente" na maioria dessas instâncias? É o servidor que está processando a solicitação e servindo uma resposta, o cliente apenas processa a resposta? Nesse caso, um código 5xx seria bom, pois é um erro do servidor, não um erro do cliente?
precisa saber é o seguinte

2
o problema com todos os códigos de erro é que eles têm significado dentro de http. 500 é o único código que é apropriado para quando o serviço gera uma exceção
Ewan

9

Além da resposta muito boa de @ Ewan:

Se a consulta for do tipo que retorna um conjunto de resultados, o conjunto vazio é logicamente tão apropriado quanto um conjunto de um ou mais. De um modo geral, pelas razões indicadas pelo @Ewan, é mais prejudicial do que benéfico alterar o conjunto vazio para um erro e é simplesmente desnecessário.

Se a consulta for do tipo que procura e retorna um singleton específico (que se espera que seja encontrado, por exemplo, correspondência exata por ID), então não encontrado é uma resposta possível logicamente apropriada.


Sim, eu pensei exatamente isso na resposta de Ewan.
Walfrat 29/09/17

5

Você está assumindo que o código precisa executar uma ação especial quando não há dados retornados, mas esse pode não ser o caso. O código pode estar simplesmente procurando uma contagem de produtos ou anexando os resultados a uma lista ou a várias coisas. Você só deve dar ao usuário um "erro" se houver realmente um erro.


3
"Você deve apenas dar ao usuário um" erro "se houver realmente um erro." - isto. Um conjunto de resultados vazio ao executar uma "pesquisa" normalmente não é um "erro". No entanto, se a conexão com o banco de dados falhar, o que significa que a pesquisa não poderia ser realmente executada, um conjunto de resultados vazio (e nenhum erro) seria ambíguo. Algum tipo de estado de erro seria apropriado nesse caso (talvez junto com um conjunto de resultados vazio - dependendo de como a API está definida).
precisa saber é o seguinte

0

Quando uso uma API, como cliente, tenho que lidar com casos de "sucesso" diferentes de casos de "erro"; Eu não tenho escolha lá. Portanto, você deve retornar um erro em situações que o cliente deseja tratar de maneira diferente e êxito em situações que o cliente deseja tratar da mesma forma.

Se eu fizer uma consulta que, em teoria, possa retornar qualquer número de resultados, zero, um, duzentos e assim por diante, você deverá retornar "sucesso" sempre que a API fornecer a lista completa de todos os resultados. E, possivelmente, nos casos em que existem muitos resultados, você retornou uma lista parcial de resultados para evitar um tamanho excessivo e existe uma maneira acordada de como eu obteria os outros resultados. Isso porque, como cliente, muitas vezes eu quero lidar com o caso de zero resultado, como o caso de mais resultados. Eu posso tratá-lo de maneira diferente, mas não quero ser forçado.

É diferente no caso em que procuro um valor. Espero exatamente um resultado, o valor que estou procurando. E preciso desse resultado para continuar o que quero fazer de maneira significativa. Aqui é muito mais aceitável retornar um status 404 para o caso em que nenhum valor existe, porque eu preciso lidar com esse caso de maneira diferente.

Resumo: se o cliente espera qualquer número de resultados, de zero a números grandes, retorne "êxito" se todos os resultados forem entregues, mesmo que o número seja zero. Se o cliente espera exatamente um resultado, retorne êxito se o resultado for encontrado e um erro se o resultado não for encontrado.

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.