Existe-t-il des normes ou des meilleures pratiques pour structurer les réponses JSON à partir d'une API? De toute évidence, les données de chaque application sont différentes, de sorte que je ne m'inquiète pas, mais plutôt de la "réponse standard", si vous voulez. Un exemple de ce que je veux dire:
Demande réussie:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
Échec de la demande:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
Réponses:
Oui, il y a quelques normes (bien que certaines libertés sur la définition de la norme) qui ont émergé:
Il existe également des formats de description de l'API JSON:
la source
Guide Google JSON
Retour de réponse de succès
data
Retour de réponse d'erreur
error
et si votre client est JS, vous pouvez utiliser
if ("error" in response) {}
pour vérifier s'il y a une erreur.la source
error
, la page de Google en donne un exempleJe suppose qu'une norme de facto n'a pas vraiment émergé (et peut-être jamais). Mais peu importe, voici mon point de vue:
Demande réussie:
Échec de la demande:
Avantage: mêmes éléments de niveau supérieur dans les cas de réussite et d'erreur
Inconvénient: pas de code d'erreur, mais si vous le souhaitez, vous pouvez soit changer le statut en code (de réussite ou d'échec), soit ajouter un autre élément de niveau supérieur nommé "code".
la source
messages
qui est un tableau de messages au lieu d'une seule chaîne.fail
pour les problèmes de validation typiques, alors qu'ilerror
n'est utilisé qu'avec des erreurs fatales comme les erreurs de base de données.200
dans les en-têtes pourquoi avez-vous même besoin d'unstatus
champ? renvoyez simplement l'objet de données directement. Vous savez que cela peut causer des problèmes supplémentaires avec les langages FE typés comme TypeScript.En supposant que votre question concerne la conception des services Web REST et plus précisément le succès / l'erreur.
Je pense qu'il existe 3 types différents de design.
Utilisez uniquement le code d'état HTTP pour indiquer s'il y a eu une erreur et essayez de vous limiter aux erreurs standard (cela devrait généralement suffire).
Utilisez HTTP Status + json body (même s'il s'agit d'une erreur). Définissez une structure uniforme pour les erreurs (ex: code, message, raison, type, etc.) et utilisez-la pour les erreurs.Si c'est un succès, renvoyez simplement la réponse json attendue.
Oubliez le statut http (ex: toujours le statut 200), utilisez toujours json et ajoutez à la racine de la réponse un boolean responseValid et un objet d'erreur (code, message, etc.) qui sera renseigné s'il s'agit d'une erreur sinon les autres champs (succès) sont peuplés.
Avantages: Le client ne traite que le corps de la réponse qui est une chaîne json et ignore le statut (?).
Inconvénients: le moins standard.
A vous de choisir :)
Selon l'API, je choisirais 2 ou 3 (je préfère 2 pour les apis json rest). Une autre chose que j'ai connue dans la conception de REST Api est l'importance de la documentation pour chaque ressource (URL): les paramètres, le corps, la réponse, les en-têtes, etc. + exemples.
Je vous recommanderais également d'utiliser jersey (implémentation jax-rs) + genson (bibliothèque de java / json). Vous n'avez qu'à déposer genson + jersey dans votre classpath et json est automatiquement pris en charge.
ÉDITER:
La solution 2 est la plus difficile à mettre en œuvre, mais l'avantage est que vous pouvez bien gérer les exceptions et pas seulement les erreurs commerciales, l'effort initial est plus important mais vous gagnez sur le long terme.
La solution 3 est facile à implémenter à la fois, côté serveur et client, mais ce n'est pas aussi agréable que vous devrez encapsuler les objets que vous souhaitez renvoyer dans un objet de réponse contenant également l'erreur responseValid +.
la source
Le RFC 7807: Détails du problème pour les API HTTP est actuellement la chose la plus proche que nous ayons d'une norme officielle.
la source
Voici l'instagram au format json utilisé
la source
Je ne serai pas aussi arrogant pour prétendre qu'il s'agit d'une norme, je vais donc utiliser le formulaire "Je préfère".
Je préfère une réponse concise (lorsque je demande une liste de / articles, je veux un tableau JSON d'articles).
Dans mes conceptions, j'utilise HTTP pour le rapport d'état, un 200 renvoie juste la charge utile.
400 renvoie un message de ce qui n'allait pas avec la demande:
Renvoyer 404 si le modèle / contrôleur / URI n'existe pas
S'il y a eu une erreur de traitement de mon côté, je retourne 501 avec un message:
D'après ce que j'ai vu, un certain nombre de cadres REST-ish ont tendance à aller dans ce sens.
Raisonnement :
JSON est censé être un format de charge utile , ce n'est pas un protocole de session. L'idée globale des charges utiles de session-ish verbeuse vient du monde XML / SOAP et de divers choix malavisés qui ont créé ces conceptions gonflées. Après avoir réalisé que tout cela était un énorme mal de tête, le but de REST / JSON était de le BAISER et d'adhérer à HTTP. Je ne pense pas qu'il y ait quoi que ce soit à distance standard dans les deux JSend et surtout pas avec les plus verbeux d'entre eux. XHR réagira à la réponse HTTP, si vous utilisez jQuery pour votre AJAX (comme la plupart le font), vous pouvez utiliser
try
/catch
etdone()
/fail()
callbacks pour capturer les erreurs. Je ne vois pas comment l'encapsulation des rapports d'état dans JSON est plus utile que cela.la source
Pour ce que ça vaut, je fais ça différemment. Un appel réussi n'a que les objets JSON. Je n'ai pas besoin d'un objet JSON de niveau supérieur qui contient un champ de réussite indiquant vrai et un champ de charge utile qui a l'objet JSON. Je viens de renvoyer l'objet JSON approprié avec un 200 ou tout ce qui est approprié dans la plage 200 pour le statut HTTP dans l'en-tête.
Cependant, s'il y a une erreur (quelque chose dans la famille 400), je retourne un objet d'erreur JSON bien formé. Par exemple, si le client POSTE un utilisateur avec une adresse e-mail et un numéro de téléphone et que l'un d'eux est mal formé (c'est-à-dire que je ne peux pas l'insérer dans ma base de données sous-jacente), je retournerai quelque chose comme ceci:
Les bits importants ici sont que la propriété "field" doit correspondre exactement au champ JSON qui n'a pas pu être validé. Cela permet aux clients de savoir exactement ce qui n'a pas fonctionné avec leur demande. En outre, "message" se trouve dans les paramètres régionaux de la demande. Si "emailAddress" et "phoneNumber" n'étaient pas valides, le tableau "erreurs" contiendrait des entrées pour les deux. Un corps de réponse JSON 409 (conflit) pourrait ressembler à ceci:
Avec le code d'état HTTP et ce JSON, le client a tout ce dont il a besoin pour répondre aux erreurs de manière déterministe et il ne crée pas une nouvelle norme d'erreur qui tente de remplacer les codes d'état HTTP. Notez que cela ne se produit que pour la plage de 400 erreurs. Pour tout ce qui est dans la gamme 200, je peux simplement retourner tout ce qui est approprié. Pour moi, c'est souvent un objet JSON de type HAL, mais cela n'a pas vraiment d'importance ici.
La seule chose que j'ai pensé à ajouter était un code d'erreur numérique soit dans les entrées du tableau "erreurs", soit à la racine de l'objet JSON lui-même. Mais jusqu'à présent, nous n'en avons pas eu besoin.
la source
Il n'y a pas d'accord sur les autres formats de réponse api des grands géants du logiciel - Google, Facebook, Twitter, Amazon et autres, bien que de nombreux liens aient été fournis dans les réponses ci-dessus, où certaines personnes ont essayé de normaliser le format de réponse.
Comme les besoins des API peuvent différer, il est très difficile de faire participer tout le monde et de convenir d'un certain format. Si vous avez des millions d'utilisateurs utilisant votre API, pourquoi changeriez-vous votre format de réponse?
Voici mon point de vue sur le format de réponse inspiré par Google, Twitter, Amazon et certains messages sur Internet:
https://github.com/adnan-kamili/rest-api-response-format
Fichier Swagger:
https://github.com/adnan-kamili/swagger-sample-template
la source
Le point de JSON est qu'il est complètement dynamique et flexible. Pliez-le à votre guise, car il s'agit simplement d'un ensemble d'objets et de tableaux JavaScript sérialisés, enracinés dans un seul nœud.
C'est vous qui décidez du type du nœud racine, ce qu'il contient, si vous envoyez des métadonnées avec la réponse, c'est vous qui décidez, si vous définissez le type mime
application/json
ou si vous le laissez teltext/plain
qu'il vous appartient ( tant que vous savez comment gérer les cas de bord).Créez un schéma léger que vous aimez.
Personnellement, j'ai trouvé que le suivi analytique et le service mp3 / ogg et le service de galerie d'images et la messagerie texte et les paquets réseau pour les jeux en ligne, et les articles de blog et les commentaires de blog ont tous des exigences très différentes en termes de ce qui est envoyés et ce qui est reçu et comment ils doivent être consommés.
Donc, la dernière chose que je voudrais, en faisant tout cela, est d'essayer de rendre chacun conforme au même standard standard, qui est basé sur XML2.0 ou quelque chose du genre.
Cela dit, il y a beaucoup à dire pour utiliser des schémas qui ont du sens pour vous et sont bien pensés.
Lisez simplement certaines réponses de l'API, notez ce que vous aimez, critiquez ce que vous n'aimez pas, notez ces critiques et comprenez pourquoi elles vous frottent dans le mauvais sens, puis réfléchissez à la façon d'appliquer ce que vous avez appris à ce dont vous avez besoin.
la source
JSON-RPC 2.0 définit un format standard de demande et de réponse, et est une bouffée d'air frais après avoir travaillé avec les API REST.
la source
code
champ à être une chaîne. Heureusement, la spécification nous permet de remplir toutes les informations que nous voulons dans ledata
champ de l'erreur . Dans mes projets JSON-RPC, j'utilise généralement un code numérique unique pour toutes les erreurs de couche application (par opposition à l'une des erreurs de protocole standard). Ensuite, j'ai mis les informations détaillées sur l'erreur (y compris un code de chaîne indiquant le type d'erreur réel) dans ledata
champ.Pour ceux qui viendront plus tard, en plus de la réponse acceptée qui inclut HAL, JSend et JSON API, j'ajouterais quelques autres spécifications qui méritent d'être examinées:
la source
Le cadre de base suggéré semble bien, mais l'objet d'erreur tel que défini est trop limité. Souvent, on ne peut pas utiliser une seule valeur pour exprimer le problème, et au lieu de cela, une chaîne de problèmes et de causes est nécessaire .
J'ai fait quelques recherches et j'ai découvert que le format le plus courant pour renvoyer une erreur (exceptions) est une structure de ce formulaire:
C'est le format proposé par la norme de données OASIS OASIS OData et semble être l'option la plus standard, mais il ne semble pas y avoir de taux d'adoption élevés d'aucune norme à ce stade. Ce format est conforme à la spécification JSON-RPC.
Vous pouvez trouver la bibliothèque open source complète qui implémente cela à: Mendocino JSON Utilities . Cette bibliothèque prend en charge les objets JSON ainsi que les exceptions.
Les détails sont abordés dans mon article de blog sur la gestion des erreurs dans l'API JSON REST
la source
Il n'y a aucune norme contraire à la loi ou illégale autre que le bon sens. Si nous résumons cela comme deux personnes parlant, la norme est la meilleure façon de se comprendre avec précision en un minimum de mots en un minimum de temps. Dans notre cas, «mots minimum» optimise la bande passante pour l'efficacité du transport et «comprendre avec précision» est la structure pour l'efficacité de l'analyseur; qui finit par se retrouver avec moins de données, et la structure commune; de sorte qu'il peut passer par un trou d'épingle et peut être analysé à travers une portée commune (au moins initialement).
Presque dans tous les cas suggérés, je vois des réponses distinctes pour le scénario «Succès» et «Erreur», ce qui est une sorte d'ambiguïté pour moi. Si les réponses sont différentes dans ces deux cas, alors pourquoi devons-nous vraiment y placer un indicateur de «réussite»? N'est-il pas évident que l'absence d '«erreur» est un «succès»? Est-il possible d'avoir une réponse où «Succès» est VRAI avec un «Erreur» défini? Ou la façon dont le «succès» est FAUX sans aucune «erreur» définie? Un seul drapeau ne suffit pas? Je préférerais avoir le drapeau "Erreur" uniquement, car je pense qu'il y aura moins "Erreur" que "Succès".
De plus, devrions-nous vraiment faire de «l'erreur» un indicateur? Et si je veux répondre avec plusieurs erreurs de validation? Donc, je trouve plus efficace d'avoir un nœud «Erreur» avec chaque erreur comme enfant sur ce nœud; où un noeud «Erreur» vide (compte jusqu'à zéro) dénoterait un «Succès».
la source
Meilleure réponse pour les API Web facilement compréhensibles par les développeurs mobiles.
C'est pour la réponse "succès"
C'est pour la réponse "Erreur"
la source