web-dev-qa-db-fra.com

API RESTful - Comportement correct lorsque des paramètres non essentiels/non demandés sont passés dans la requête

Nous développons actuellement une API RESTful qui accepte les paramètres de requête dans la requête sous la forme de données codées JSON.

Nous nous demandions quel est le comportement correct lorsque les paramètres non demandés/non attendus sont transmis avec ceux qui sont requis.

Par exemple, nous pouvons exiger qu'une demande PUT sur un noeud final donné fournisse exactement deux valeurs respectivement pour les clés name et nom de famille :

{
    "name": "Jeff",
    "surname": "Atwood"
}

Que se passe-t-il si une clé parasite est également passée, comme color dans l'exemple ci-dessous?

{
    "name": "Jeff",
    "surname": "Atwood",

    "color": "red"
}

La valeur pour couleur n'est pas attendue, ni documentée.

Devrions-nous l'ignorer ou rejeter la demande avec une erreur d'état BAD_REQUEST 400?

Nous pouvons affirmer que la demande est incorrecte car elle n'est pas conforme à la documentation. Et probablement, l'utilisateur de l'API devrait en être averti (elle a transmis la valeur, elle s'attend à quelque chose pour cela.)

Mais nous pouvons aussi affirmer que la demande peut être acceptée car, les paramètres requis étant tous fournis, elle peut être remplie.

16
Paolo

Ayant utilisé des API RESTful de nombreux fournisseurs au fil des ans, permettez-moi de vous présenter le point de vue de "l'utilisateur".

Souvent, la documentation est simplement mauvaise ou périmée. Peut-être qu'un nom de paramètre a changé, peut-être que vous imposez une casse exacte sur les noms de propriété, peut-être avez-vous utilisé la mauvaise police dans votre documentation et avez-vous unIqui ressemble exactement à un l - oui, ceux sont des lettres différentes.

Ne l'ignore pas. Au lieu de cela, renvoyez un message d'erreur indiquant le nom de la propriété avec un message facile à comprendre. Par exemple, " Nom de propriété inconnu: color ". 

Cette petite chose contribuera grandement à limiter les demandes d'assistance concernant la consommation de votre API. 

Si vous ignorez simplement les paramètres, un développeur peut penser que des valeurs valides sont transmises lors du démarrage de votre API car évidemment l'API ne fonctionne pas correctement.

Si vous envoyez un message d'erreur générique, les développeurs devront se tirer les cheveux en essayant de comprendre ce qui se passe et d'inonder votre forum, ce site ou votre téléphone vous appellera pour vous demander pourquoi vos serveurs ne fonctionnent pas. (J'ai récemment rencontré ce problème avec un fournisseur qui ne comprenait tout simplement pas qu'un message 404 n'était pas une réponse valide à un paramètre incorrect et que la documentation devait refléter les noms de paramètre réellement utilisés ...)

De même, je m'attendrais à ce que vous donniez également un bon message d'erreur lorsqu'un paramètre requis est manquant. Par exemple "Propriété requise: le nom est manquant" .


En gros, vous voulez être le plus utile possible pour que les utilisateurs de votre API puissent être aussi autonomes que possible. Comme vous pouvez le constater, je ne partage pas du tout mon désaccord avec une ventilation "gracieuse" ou "sévère". Plus vous êtes "aimable", plus les utilisateurs de votre API risquent de se heurter à des problèmes dans lesquels ils pensent ils agissent correctement, mais obtiennent des comportements inattendus de votre API. Vous ne pouvez pas imaginer toutes les façons possibles pour que les gens fassent des erreurs, alors appliquer strictement les messages d'erreur pertinents vous aidera énormément.

33
NotMe

Si vous créez une API, vous pouvez suivre deux chemins: "stern" ou "gracious". 

  • Stern signifie: Si vous faites quelque chose que je ne pensais pas, je serai en colère contre vous. 
  • Gracieux signifie: si je sais ce que vous voulez et que vous pouvez y répondre, je le ferai.

REST permet une conception d'API merveilleuse et gracieuse et j'essayerais de suivre cette voie aussi longtemps que possible et d'attendre la même chose de mes clients. Si mon API évolue, il se peut que je devrais ajouter à mes réponses des paramètres supplémentaires qui ne concernent que des clients spécifiques. Si mes clients sont gentils avec moi, ils seront capables de gérer cela. Cela dit, je tiens à ajouter qu’il existe une place pour la conception d’API strictes. Si vous concevez dans un domaine sensible (par exemple, les transactions en espèces) et que vous ne voulez pas laisser de place à un malentendu entre le client et le serveur. Imaginez la demande POST suivante (valide pour votre/compte/{no}/transaction/API):

{ amount: "-100", currency : "USD" }

Que feriez-vous avec ce qui suit (demande d'API invalide)?

{ amount: "100", currency : "USD", type : "withdrawal" }

Si vous ignorez simplement l'attribut "type", vous déposerez 100 USD au lieu de les retirer. Dans un tel domaine, je suivrais une approche sévère et ne ferais montre d'aucune grâce.

Soyez courtois si vous le pouvez, soyez sévère si vous le devez.

Mise à jour:

Je suis totalement d'accord avec La réponse de @Chris Lively que l'utilisateur devrait être informé. Je ne suis pas d'accord pour dire qu'il devrait toujours y avoir une erreur, même si le message n'est pas ambigu pour la ressource référencée. Sinon, cela entravera la réutilisation des représentations de ressources et nécessitera le reconditionnement d’informations sémantiquement identiques.

17
xwoker

Cela dépend de votre documentation .. à quel point vous voulez être strict .. 
Mais communément, Just ignore it. La plupart des autres serveurs ignorent également les paramètres de requête qu’ils ne comprennent pas.

Exemple tiré de mon post précédent 

Paramètres de requête supplémentaires dans la REST URL URL

"" "Google ignore mes deux paramètres supplémentaires ici https://www.google.com/#q=search+for+something&invalid=param&more=stuff " ""

0
Vineet Singla

Ignore les.

Ne donnez à l'utilisateur aucune possibilité de procéder au reverse engineering de votre API RESTful par le biais de vos messages d'erreur.

Donnez aux développeurs la documentation la plus nette, la plus claire et la plus complète et analysez uniquement les paramètres dont votre API a besoin et que vous supportez.

0
Simone Conti

Imaginez que j'ai le schéma JSON suivant:

{
   "frequency": "YEARLY",
   "date": 23,
   "month": "MAY",
}

L'attribut de fréquence accepte les valeurs "HEBDOMADAIRE", "MENSUELLE" et "ANNUELLE". La charge utile attendue pour la valeur de fréquence "HEBDOMADAIRE" est la suivante:

{
   "frequency": "WEEKLY",
   "day": "MONDAY",
}

Et la charge utile attendue pour la valeur de fréquence "MENSUEL" est:

{
   "frequency": "MONTHLY",
   "date": 23,
}

Indiquez le schéma JSON ci-dessus. En général, vous aurez besoin d’un POJO contenant des champs de fréquence, de jour, de date et de mois pour la désérialisation.

Si la charge reçue est:

{
   "frequency": "MONTHLY",
   "day": "MONDAY",
   "date": 23,
   "year": 2018
}

Je vais lancer une erreur sur l'attribut "day" parce que je ne saurai jamais l'intention de l'expéditeur:

  1. fréquence: "HEBDOMADAIRE" et jour: "LUNDI" (valeur de fréquence incorrecte entrée), ou
  2. fréquence: "MENSUEL" et date: 23 

Pour l'attribut "année", je n'ai pas vraiment le choix. Même si je souhaite émettre une erreur pour cet attribut, il se peut que je ne puisse pas le faire. Il est ignoré par la bibliothèque de sérialisation/désérialisation JSON car mon POJO ne possède pas cet attribut. Et c’est le comportement de GSON et cela a du sens compte tenu de la décision de conception.

Navigation dans l'arborescence Json ou l'arborescence de types cible lors de la désérialisation

Lorsque vous désérialisez une chaîne Json en un objet du type souhaité, vous pouvez naviguer dans l'arborescence de l'entrée ou dans l'arborescence du type souhaité. Gson utilise la dernière approche pour naviguer dans le type d'objet cible. Cela vous permet de garder un contrôle strict sur l'instanciation du type d'objets que vous attendez (essentiellement en validant l'entrée par rapport au "schéma" attendu). En faisant cela, vous ignorez également tous les champs supplémentaires que l’entrée Json contient mais n’était pas attendus.

Dans le cadre de Gson, nous avons écrit un ObjectNavigator à usage général qui peut prendre n’importe quel objet et naviguer dans ses champs en appelant le visiteur de votre choix.

Extrait de GSON Design Document

0
maximilianus