Notre service est actuellement dans 5 villes. Si quelqu'un essaie d'appeler notre API de service à partir d'une autre ville, nous voulons lancer cette erreur Service not available in your area
.
La question est, quel serait le code http approprié pour cette erreur?
ou autre chose?
Tout code d'erreur HTTP serait inapproprié. Il n'y a aucune erreur ou problème d'aucune sorte du point de vue HTTP, il devrait donc être quelque chose dans la plage 200. Vous informez poliment certains de vos utilisateurs qu'ils ne seront pas desservis en renvoyant un document qui le leur dit. Et tout cela se passe bien.
L'utilisateur ne pourra pas utiliser votre application . Il s'agit d'une décision consciente prise par votre logique métier, et non d'un incident. Au niveau HTTP, tout est honky dory.
Modifier
Il semble que ce que nous regardons ici soit un choc entre la vieille école et la nouvelle école. Lorsque HTTP a été conçu, il n'y avait pas de services Web, il n'y avait pas de SOAP, pas de JSON, pas de principes REST. En tant que protocole ci-dessus TCP cela était déjà considéré (près de) le niveau de l'application et de nombreux codes de statut de haut niveau ont été définis. Lorsque le Web a commencé à être utilisé pour des services de haut niveau plus riches et un moyen commun de transporter les "enveloppes" était nécessaire, les concepteurs ont détourné le HTTP plutôt que de définir un nouveau et un protocole plus propre, juste parce que HTTP était omniprésent.
Ainsi, dans un contexte de service Web moderne, HTTP est en effet un peu plus qu'une couche de transport stupide et la plupart de ses codes peuvent être considérés comme non applicables ou obsolètes. Il suffit d'en choisir un car il se rapproche de l'état de votre application et se trouve dans cette liste qui signifiait autrefois que quelque chose peut sembler inoffensif, mais je pense que cela enverrait un mauvais message. Vous ne voulez pas que HTTP joue ce rôle de régulation dans un contexte de service Web.
5xx
les erreurs sont des erreurs de serveur - quelque chose s'est mal passé sur le serveur. En particulier, un 5 indique que:
le serveur n'est actuellement pas en mesure de traiter la demande en raison d'une surcharge temporaire ou d'une maintenance planifiée
4xx
les erreurs sont des erreurs du client - le client fait une demande que le serveur ne peut pas ou ne veut pas remplir. En particulier, un 4 indique que
le serveur a compris la demande mais refuse de l'autoriser. Un serveur qui souhaite rendre public pourquoi la demande a été interdite peut décrire cette raison dans la charge utile de la réponse (le cas échéant). [..] Cependant, une demande peut être interdite pour des raisons sans rapport avec les informations d'identification.
Je dirais que 503
est clairement incorrect, car il ne s'agit pas d'un problème temporaire - vous ne supportez pas les demandes dans ce domaine, point final. L'argument pourrait être avancé que vous espérez éventuellement prendre en charge la zone, mais le but du code est d'inclure un en-tête indiquant quand le client peut réessayer. "Dans 6 mois" n'adhère pas à l'intention.
403
est un meilleur choix car votre service interdit simplement les demandes de certains paramètres régionaux.
Ni l'un ni l'autre.
Si votre API est bien conçue, l'URL inclut le nom de la ville, par exemple.
http://example.com/API/Vienna/HailRide
ou
http://example.com/API/HailRide?city=Vienna
étant donné que la géolocalisation IP n'est pas fiable, vos utilisateurs peuvent utiliser des VPN, vos utilisateurs peuvent souhaiter héler un tour pour quelqu'un d'autre, etc. Le client API propose une ville (- == --- ==) la responsabilité de. Habituellement, le client dispose de bien meilleures ressources pour déterminer l'emplacement de l'utilisateur (par exemple, le service de localisation d'un appareil mobile).
Une fois que vous avez fait cela, la bonne réponse à
http://example.com/API/SomeUnsupportedCity/HailRide
ou
http://example.com/API/HailRide?city=SomeUnsupportedCity
devient évident: 404 Introuvable: Aucune ressource pour héler un trajet à SomeUnsupportedCity n'existe.
Cela ressemble à une question de trou rond/cheville carrée. Pourquoi votre seule réponse doit-elle être un code HTTP? Les codes d'erreur HTTP ne peuvent pas couvrir tous les cas d'utilisation.
Tous vos appels API doivent avoir une messagerie supplémentaire qui revient - c'est-à-dire un petit message d'erreur JSON. Donnez-leur un 403 (car, vraiment, ils n'ont pas la permission d'utiliser l'API étant donné l'emplacement) et renvoyez un peu d'informations supplémentaires comme vous le suggérez.
Si vous ne le faites pas, la prochaine fois, vous demanderez quel code d'erreur HTTP retourner lorsque l'utilisateur a demandé un SUV, mais que seule une Prius est disponible.
Quelques-uns ont du sens.
403 Interdit, pour les raisons qui Eric Stein mentionne dans sa réponse . Vous pouvez utiliser diverses informations fournies par la demande pour déterminer où se trouve le client et qui est le client et, sur la base de cette demande, le serveur ne peut pas ou ne veut pas répondre.
Cependant, je proposerais également 451 Non disponible pour des raisons juridiques comme statut de retour possible pour certains cas. Ce statut ne vous oblige à inclure (dans les en-têtes) un lien vers la législation pertinente. C'est spécifiquement pour les cas où il n'est pas légal pour le client d'accéder à vos ressources, et aucun cas plus général du client n'existe dans une région ou une zone non prise en charge.
J'éviterais la série de statuts 5xx - ils indiquent souvent des problèmes techniques côté serveur. Cela ne semble pas être le cas ici.
Si la restriction est due à des raisons légales, le code d'erreur HTTP approprié est HTTP 451, "Non disponible pour des raisons légales."
Ceci est généralement utilisé dans le cas de matériel qui a été révoqué en raison d'une action DMCA ou de poursuites judiciaires en raison de campagnes de harcèlement ou similaires, mais le esprit et lettre de la définition de la réponse indique:
Ce document spécifie un code d'état HTTP (Hypertext Transfer Protocol) à utiliser lorsque l'accès aux ressources est refusé en raison de demandes légales.
Le code lui-même est une référence à Fahrenheit 451 par Ray Bradbury.
Les gens oublient souvent que les codes de statut HTTP sont extensibles.
Les codes d'état HTTP sont extensibles. Les applications HTTP ne sont pas nécessaires pour comprendre la signification de tous les codes d'état enregistrés, bien qu'une telle compréhension soit évidemment souhaitable. Cependant, les applications DOIVENT comprendre la classe de tout code d'état, comme indiqué par le premier chiffre, et traiter toute réponse non reconnue comme étant équivalente au code d'état x00 de cette classe, à l'exception qu'une réponse non reconnue NE DOIT PAS être mise en cache. Par exemple, si un code d'état non reconnu de 431 est reçu par le client, il peut sans risque supposer qu'il y a eu un problème avec sa demande et traiter la réponse comme s'il avait reçu un code d'état 400. Dans de tels cas, les agents utilisateurs DEVRAIENT présenter à l'utilisateur l'entité retournée avec la réponse, car cette entité est susceptible d'inclure des informations lisibles par l'homme qui expliqueront le statut inhabituel.
https://tools.ietf.org/html/rfc2616#section-6.1.1
Vous pouvez toujours simplement créer votre propre code d'état dans la plage 4 pour une utilisation par votre API et votre application cliente.
Au début, je pensais que 503 parce que la description "service indisponible" semble correspondre au problème, mais en regardant définitions , 503 est vraiment spécifique à l'indisponibilité du serveur. En y réfléchissant plus, vous dites au client qu'il y a un problème avec la demande, pas qu'il y a un problème côté serveur.
403 est plus proche parce que vous dites à l'utilisateur que vous avez reçu le message et que vous le comprenez mais que le serveur n'est pas disposé à le satisfaire. Cela peut prêter à confusion et une explication textuelle peut être ajoutée pour décrire le scénario. Selon la RFC, 404 est également un substitut valide pour ce code.
À moins que quelqu'un n'ait imaginé un nouveau code pour cela, 403 ou 404 semblent être les plus proches.
Vous devez faire correspondre la description de l'erreur avec le code que vous donnez:
si tu le dis Service not available in your area.
alors vous devriez donner un 404
parce que vous prétendez que le service n'est pas disponible.
si tu le dis You are not authorized for this service in your area.
alors vous devriez donner un 403
parce que vous prétendez que l'appelant n'est pas autorisé.
J'irais pour la seconde.
Il y a version Internet actuelle (qui expirera le 31 décembre 2018) qui propose des modifications au HTTP 451 non disponible pour des raisons juridiques statut. Le projet suggère qu'une réponse 451 contienne un geo-scope-block
en-tête qui doit "correspondre à la liste séparée par des virgules des codes de pays alpha-2 définis dans [ISO.3166-1]". Cependant, le projet précise également que le code 451 ne doit pas être utilisé "par un opérateur pour refuser l'accès à une ressource sur la base d'une politique spécifiée par l'opérateur (par opposition à une demande légale imposée à l'opérateur)".
Donc, en supposant que vous n'avez pas de demande légale pour le géobloc, 451 n'est pas le bon code. Quel est le bon code alors? Eh bien, de nombreuses autres réponses ont déjà été suggérées 403 Interdit , mais elles semblent toutes être "basées sur l'opinion", alors voyons ce que font les autres:
Il n'y a donc pas de solution universelle unique, il vous suffit de choisir celle qui vous convient le mieux. Mais quel que soit votre choix, assurez-vous d'expliquer le problème réel dans le corps de la réponse .
Je dirais qu'il n'y aurait rien de mal à simplement spécifier un code d'état HTTP personnalisé, comme RubberDuck a déjà répond . Un code d'état personnalisé dans la plage 400 pourrait même être un très bon appel, car cela attirera certainement l'attention des développeurs s'ils voient quelque chose comme "HTTP status 499". Un "403" est trop facile à passer en tant que " OK donc j'ai eu un mauvais mot de passe, essayons autre chose à la place", et cela se traduit par des heures perdues.