Je vais décrire un exemple:
Je commence à créer une API pour une boulangerie. L'API permettra aux utilisateurs de rechercher dans leur catalogue des produits de boulangerie, tels que des biscuits aux pépites de chocolat faits maison à l'aide de api.examplebakery.com/search?q=.....
.
Quelqu'un l'utilise pour rechercher un produit nommé pineapple-banana flavoured cookies
et ne trouvera évidemment aucun résultat.
Doit-il être renvoyé comme une erreur? La recherche n'a pas échoué, l'API a recherché et conclu avec succès qu'aucun cookie n'a pu être trouvé. L'API ne doit pas renvoyer 404
, car l'API a bien été trouvée.
Lorsqu'il y a des résultats, la sortie est une liste (JSON, basée sur votre commentaire). Pour les requêtes sans résultat, la sortie doit être exactement la même. La liste contient simplement 0 éléments.
Donc, si votre réponse est normalement la suivante:
{
"results": [
{
"name": "Pancakes",
....
},
{
"name": "French Fries",
....
}
]
}
Ensuite, pour une requête avec 0 résultats, ce devrait être ceci:
{
"results": []
}
Si vous incluez également des métadonnées sur le nombre de "pages" de résultats, des liens vers ces "pages", etc., je vous suggère de dire qu'il y a 1 "page".
Le statut HTTP doit être le même que lorsqu'il y a des résultats - 200 OK
.
204 No Content
peut également sembler être une option, mais ce n'est pas parce que vous renvoyez en fait du "contenu" - la liste vide. Si vous pensez qu'une liste vide ne compte pas comme "contenu", que se passe-t-il si vous modifiez ensuite la réponse pour proposer des suggestions d'orthographe? Le noyau de la réponse sera toujours une liste vide, mais maintenant il y a encore plus de "contenu".
Pour plus d'informations utiles sur les codes d'état HTTP, jpmc26 a une réponse vaut la peine d'être lu.
Chaque fois que vous décidez d'un code HTTP, vous devriez toujours poser cette question:
Que peut/voudra/devrait faire un client arbitraire avec la réponse?
Décidez toujours dans quelle plage votre code de réponse doit être en premier. Cela élimine rapidement de nombreux codes de réponse en option et (peut-être plus important encore), il est beaucoup plus simple de suivre la sémantique des codes. Voir les premières sections de la documentation du code HTTP pour les explications de ce que chaque catégorie de codes représente.
Dans ce cas, le client a demandé une liste de résultats avec un filtre à partir d'un point de terminaison existant et valide et a l'autorisation d'y accéder. Le serveur a pu traiter la demande et déterminer les données appropriées à renvoyer (aucun élément), si bien que la demande a abouti. Il se trouve que le filtre qu'ils ont donné a filtré tous les résultats. Il n'appartient pas au serveur de déterminer si c'est ce que le client voulait ou non, car cela peut être un résultat attendu pour certains clients. S'il s'agit en quelque sorte d'un problème pour le code client, c'est la responsabilité du client de déterminer, vérifier et gérer de manière appropriée. Il s'agit donc clairement de 2xx.
Maintenant, la question est: "Quel 2xx?" Cela dépend de la façon dont vous prévoyez que le serveur réponde.
Les autres ne s'appliquent pas du tout:
Il doit donc être 200 ou 204, et 200 est plus susceptible de conduire à un code client plus simple et plus robuste (surtout si vous utilisez une structure de réponse cohérente contenant une liste vide).
Non. L'utilisation de 404 pour indiquer "votre requête a été traitée mais il n'y a pas de correspondance" est affreuse car:
flux conditionnel basé sur la gestion des exceptions (c'est-à-dire forcer un résultat non exceptionnel à créer et gérer une exception dans le client qui peut être non performante et maladroite)
ambiguïté entre la "vraie" page introuvable, vous avez tapé les erreurs de point final
La chose à retenir est qu'il y a toujours un client pour désérialiser le message et c'est ce que ce client retourne qui est important; pas la sérialisation.
Si le client doit retourner null, utilisez la sérialisation de null. Si le client doit retourner un tableau vide, utilisez [], si le client doit renvoyer une erreur, utilisez 500 et passez le message d'erreur
Au-delà de la très bonne réponse d'Ewan @:
Si la requête est du type qui renvoie un ensemble de résultats, alors l'ensemble vide est logiquement tout aussi approprié qu'un ensemble de un ou un ensemble de plusieurs. D'une manière générale, pour les raisons exposées par @Ewan, il est plus néfaste que bénéfique de transformer l'ensemble vide en erreur et ce n'est tout simplement pas nécessaire.
Si la requête est du type qui recherche et renvoie un singleton spécifique (qui devrait être trouvé, par exemple une correspondance exacte par id), alors non trouvé est une réponse possible logiquement appropriée.
Vous supposez que le code doit effectuer une action spéciale lorsqu'aucune donnée n'est renvoyée, mais ce n'est peut-être pas le cas. Le code peut simplement rechercher un nombre de produits ou ajouter les résultats à une liste ou à un certain nombre de choses. Vous ne devez donner à un utilisateur une "erreur" que s'il y a effectivement une erreur.
Lorsque j'utilise une API, en tant que client, je dois gérer des cas de "réussite" différents des cas "d'erreur"; Je n'ai pas le choix là-bas. Par conséquent, vous devez renvoyer une erreur dans les situations que le client veut pour traiter différemment, et un succès dans les situations que le client veut pour traiter la même chose.
Si je fais une requête qui pourrait en théorie retourner n'importe quel nombre de résultats, zéro, un, deux cent et ainsi de suite, alors vous devriez retourner "succès" chaque fois que l'API fournit la liste complète de tous les résultats. Et peut-être dans les cas où il y a beaucoup de résultats, vous avez renvoyé une liste partielle de résultats pour éviter une taille excessive, et il y a une façon convenue d'obtenir les autres résultats. C'est parce qu'en tant que client, je veux souvent gérer le cas de zéro résultat comme le cas de plus de résultats. Je pourrais le traiter différemment, mais je ne veux pas y être forcé.
C'est différent dans le cas où je recherche une valeur. J'attends exactement un résultat, la valeur que je recherche. Et j'ai besoin de ce seul résultat pour continuer ce que je veux faire de manière significative. Ici, il est beaucoup plus acceptable de renvoyer un état 404 pour le cas où aucune valeur n'est là, car j'ai quand même besoin de gérer ce cas différemment.
Résumé: Si le client attend un certain nombre de résultats, de zéro à un grand nombre, retourne "succès" si tous les résultats sont fournis, même si le nombre est nul. Si le client attend exactement un résultat, retournez succès si le résultat est trouvé et une erreur si le résultat n'est pas trouvé.