892 votes

Existe-t-il une norme pour le format de réponse API JSON ?

Existe-t-il des normes ou des bonnes pratiques pour structurer les réponses JSON d'une API ? Il est évident que les données de chaque application sont différentes, ce qui ne me préoccupe pas, mais plutôt le "modèle de réponse", si vous voulez. Voici un exemple de ce que je veux dire :

Demande réussie :

{
  "success": true,
  "payload": {
    /* Application-specific data would go here. */
  }
}

Requête échouée :

{
  "success": false,
  "payload": {
    /* Application-specific data would go here. */
  },
  "error": {
    "code": 123,
    "message": "An error occurred!"
  }
}

25 votes

Les gens ont probablement tiré une leçon de SOAP et ne le construiront plus...

27 votes

@dystroy : Vous pouvez expliquer votre commentaire ?

4 votes

XML a été, à mon avis, tué pour les programmeurs par un excès de normalisation résultant en un gonflement des API et des applications, ce qui a finalement conduit les gens à ne presque jamais, aujourd'hui, faire SOAP de la manière simple originale de quelques LOC mais avec des bibliothèques lentes, la paramétrisation et même des cadres de construction de code... Je suis sûr que la plupart des concepteurs d'aujourd'hui ne veulent pas que le même cauchemar se produise. Mais ce n'est qu'une opinion et je ne veux pas salir votre question avec d'autres commentaires nauséabonds.

819voto

Adam Gent Points 15055

Oui, il y a quelques normes (bien qu'il y ait quelques libertés sur la définition de norme) qui ont émergé :

  1. API JSON - L'API JSON couvre également la création et la mise à jour des ressources, et pas seulement les réponses.
  2. JSend - Simple et probablement ce que vous faites déjà.
  3. Protocole OData JSON - Très compliqué.
  4. HAL - Comme OData mais visant à être HATEOAS comme.

Il existe également des formats de description d'API JSON :

  • Swagger
    • Schéma JSON (utilisé par swagger mais vous pouvez l'utiliser seul)
  • WADL en JSON
  • RAML
  • HAL parce que HATEOAS en théorie, se décrit d'elle-même.

27 votes

Je vous remercie. JSend en particulier est exactement ce que je recherchais. Il est similaire à ce que je faisais, mais présente des avantages que ma méthode ne présentait pas. Pour être juste envers @trungly, JSend est également très proche de sa propre réponse.

11 votes

Pour les réponses aux erreurs en particulier, j'aime aussi le Détails des problèmes pour les API HTTP Projet de RFC.

1 votes

Vous voulez peut-être ajouter code.google.com/p/json-service à la liste des formats de description ?

296voto

Steely Wing Points 1857

Guide Google JSON

Retour de la réponse au succès data

{
  "data": {
    "id": 1001,
    "name": "Wing"
  }
}

Retour de la réponse d'erreur error

{
  "error": {
    "code": 404,
    "message": "ID not found"
  }
}

et si votre client est JS, vous pouvez utiliser if ("error" in response) {} pour vérifier s'il y a une erreur.

14 votes

Tout d'abord, le guide Google JSON recommande d'utiliser des guillemets doubles au lieu de guillemets simples.

2 votes

Je ne suis pas sûr que vous puissiez gérer cela à partir d'une API JSON côté serveur comme PlayJson, mais dans tous les cas, cela n'a pas d'importance. @Steely vos liens sont cassés

4 votes

Qu'en est-il des erreurs qui doivent fournir une liste d'échecs (comme les problèmes de validation) ?

183voto

trungly Points 337

Je suppose qu'une norme de facto n'a pas vraiment émergé (et pourrait ne jamais émerger). Mais quoi qu'il en soit, voici mon point de vue :

Demande réussie :

{
  "status": "success",
  "data": {
    /* Application-specific data would go here. */
  },
  "message": null /* Or optional success message */
}

Requête échouée :

{
  "status": "error",
  "data": null, /* or optional error payload */
  "message": "Error xyz has occurred"
}

Avantage : Les mêmes éléments de haut niveau dans les cas de réussite et d'erreur

Inconvénient : Pas de code d'erreur, mais si vous voulez, vous pouvez soit changer le statut pour qu'il soit un code (succès ou échec), -ou- vous pouvez ajouter un autre élément de haut niveau nommé "code".

4 votes

Oui, c'est la bonne façon si vous utilisez POJO pour le parsing json ! quand nous utilisons POJOs nous avons besoin d'un format json statique, non dynamique !

0 votes

Simple et précis. Meilleur que jsend à mon avis car jsend distingue l'erreur de l'échec.

1 votes

J'utilise aussi ce modèle mais avec un champ appelé messages qui est un tableau de messages au lieu d'une seule chaîne.

108voto

eugen Points 2101

Je suppose que votre question porte sur la conception des webservices REST et plus précisément sur le succès et l'erreur.

Je pense qu'il y a 3 types de design différents.

  1. Utilisez uniquement le code d'état HTTP pour indiquer s'il y a eu une erreur et essayez de vous limiter à celles qui sont standard (en général, cela devrait suffire).

    • Pour : Il s'agit d'un standard indépendant de votre api.
    • Contre : Moins d'informations sur ce qui s'est réellement passé.
  2. Utilisez Statut HTTP + corps json (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.

    • Pros : Toujours standard car vous utilisez les codes d'état HTTP existants et vous renvoyez un json décrivant l'erreur (vous fournissez plus d'informations sur ce qui s'est passé).
    • Inconvénients : La sortie json varie selon qu'il s'agit d'une erreur ou d'un succès.
  3. Oubliez le statut http (ex : toujours le statut 200), toujours utiliser json et ajouter à la racine de la réponse un booléen responseValid et un objet d'erreur (code, message, etc) qui sera rempli si c'est une erreur sinon les autres champs (succès) sont remplis.

    • Pour : Le client ne traite que le corps de la réponse qui est une chaîne json et ignore le statut ( ?).

    • Inconvénient : Le moins standard.

C'est à vous de choisir :)

En fonction de l'API, je choisirais 2 ou 3 (je préfère 2 pour les API de repos json). Une autre chose que j'ai expérimenté dans la conception d'Api REST 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 recommande également d'utiliser jersey (implémentation de jax-rs) + genson (bibliothèque de liaison de données java/json). Il vous suffit de déposer genson + jersey dans votre classpath et json est automatiquement pris en charge.

EDIT :

  • La solution 2 est la plus difficile à mettre en œuvre, mais l'avantage est que vous pouvez gérer les exceptions et pas seulement les erreurs de gestion. L'effort initial est plus important, mais vous gagnez sur le long terme.

  • La solution 3 est la plus facile à mettre en œuvre, tant du côté du serveur que du côté du client, mais elle n'est pas si agréable car vous devrez encapsuler les objets que vous voulez renvoyer dans un objet de réponse contenant également le responseValid + error.

2 votes

Vous dites que je devrais "Définir une structure uniforme pour les erreurs" et d'autres suggestions similaires, mais c'est précisément ce que je demande. Je suppose que la réponse s'avère être que "non, il n'y a pas de norme ou de meilleures pratiques en ce qui concerne cette structure".

8 votes

Pour mémoire : le code d'état HTTP n'est pas un en-tête.

3 votes

"la réponse ne sera pas json mais html." faux ! html n'a rien à voir avec la gestion des erreurs. la réponse peut être n'importe quel type de contenu que vous supportez.

24voto

Bojan Markovic Points 74

Je n'aurai pas l'arrogance de prétendre qu'il s'agit d'une norme et j'utiliserai donc la formule "je préfère".

Je préfère une réponse laconique (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, une 200 ne renvoie que la charge utile.

400 renvoie un message indiquant ce qui ne va pas avec la demande :

{"message" : "Missing parameter: 'param'"}

Retourner à 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 renvoie 501 avec un message :

{"message" : "Could not connect to data store."}

D'après ce que j'ai vu, un grand nombre de frameworks REST ont tendance à suivre cette voie.

Justification :

JSON est censé être un charge utile il ne s'agit pas d'un protocole de session. L'idée de charges utiles verbeuses de type session provient du monde XML/SOAP et de divers choix malencontreux qui ont créé ces conceptions gonflées. Après avoir réalisé que tout cela était un énorme casse-tête, l'objectif de REST/JSON était de le simplifier et d'adhérer à HTTP. Je ne pense pas qu'il y ait quoi que ce soit qui puisse ressembler de près ou de loin à ce que l'on pourrait appeler un " système ". standard dans l'un ou l'autre JSend et surtout pas avec le 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 et done() / fail() pour capturer les erreurs. Je ne vois pas en quoi encapsuler les rapports d'état dans JSON est plus utile que cela.

3 votes

"JSON est un format de données utiles...". Non, JSON est un format de sérialisation des données. Vous pouvez l'utiliser pour transmettre tout ce que vous voulez, y compris des protocoles de session ou de simples charges utiles. Vos commentaires sur la méthode KISS sont cependant tout à fait pertinents et indépendants de JSON. Il est préférable de garder le JSON concentré sur ce qu'il est (données de réussite ou de raison d'échec, comme vous le décrivez) plutôt que de le polluer avec un mélange des deux qui doit constamment être composé puis supprimé. Vous pouvez ensuite aller jusqu'au bout et stocker vos données JSON telles quelles dans Couchbase et les renvoyer telles quelles à l'application.

1 votes

J'aurais peut-être dû le formuler comme "censé être un format de charge utile", mais à part cela, je maintiens mon commentaire. Vous pourriez mettre les données de session/erreur comme attributs de corps dans un document HTML, mais cela ne signifie pas que c'est la bonne façon de procéder.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X