Aller au contenu principal

Réponses

doitLe résultat d'une requête POST, PUT ou PATCH doit retourner une réponse utile.

Le bon contre-exemple est la méthode DELETE, qui le plus souvent ne fait que confirmer que l'opération s'est bien déroulée : code statut 204 (donc sans corps)

Les opérations de création ou mise à jour sont censées retourner un corps représentant la ressource résultante potentiellement différente du payload de la requête.

L'identifiant d'une nouvelle ressource n'est pas censé être prédictible et connu par le client, ainsi l'opération de création doit retourner un en-tête Location avec l'URI de la ressource créée, permettant ainsi au consommateur de retrouver la ressource.

JSON et multi-représentation

Une approche encore assez répandue consiste à envisager l'utilisation de XML comme format d'échange de données, pour des raisons d'héritage du legacy (approche historique SOA). L'évolution sur le marché de l'utilisation de XML est inversement proportionnelle à JSON (qui dépasse XML depuis 2012).

Choisir XML revient à s'endetter délibérément.

Une autre approche avisée consiste à répondre à des besoins de multi-représentation et permettre au client de choisir lui-même la représentation de la ressource qui lui convient (image, pdf, …).

doitDans tous les cas le format par défaut à privilégier est JSON (fallback).

La multi-représentation d'une ressource peut techniquement être négociée de plusieurs façons :

  • par extension dans l'URL

    Exemple :

    GET /account/invoice.pdf HTTP/1.1
    Host: api.laposte.fr
  • par l'en-tête Accept

    Exemple :

    GET /account/invoice HTTP/1.1
    Host: api.laposte.fr
    Accept: image/png

D'autres méthodes existent mais sont la plupart du temps à proscrire.

devraitL'usage de l'en-tête Accept est à privilégier car plus respectueux du principe de localisation unique d'une ressource.

Schémas JSON

JSON est un format de données qui supporte la notion de schéma.

A l'instar des schémas XML (ou DTDs), les schémas JSON permettent de définir la structure d'un flux JSON ainsi que le format des valeurs d'attributs attendues.

Il existe des outils (validateurs) qui permettent de vérifier la bonne validité des documents JSON, ce qui affranchit de faire des contrôles répétés à chaque niveau de l'architecture logique de l'application.

optionL'utilisation généralisée des schémas JSON présente de nombreux avantages

Pour comprendre les schémas JSON, il suffit de retenir quelques principes simples :

  • le schéma se focalise sur la structure du document : c'est-à-dire le nom des attributs, voire le format des valeurs d'attributs, pas les valeurs elles-mêmes
  • lorsque le JSON soumis propose plus d'informations que ce qui est attendu, par défaut le schéma le tolère : cette caractéristique est intéressante pour appliquer un principe ouvert/fermé à la modélisation de la structure des flux JSON

Exemple de schéma :

{
"title": "Contact JSON schema",
"type": "object",
"properties": {
"username": { "type": "string", "unique": true },
"email": { "type": "string", "format": "email", "unique": true },
"firstName": { "type": "string" },
"lastName": { "type": "string" },
"extra": { "type": [ "object", "null" ] }
},
"additionalProperties": false,
"required": ["username", "email"]
}

Dans cet exemple, on a une bonne illustration du principe ouvert/fermé :

  • on spécifie de manière précise les différents attributs attendus pour un contact
  • on exige la présence d'un username et d'un email
  • on refuse tout attribut supplémentaire qui ne serait pas spécifié
  • on permet la fourniture de données supplémentaires dans l'attribut optionnel "extra"
devraitLes attributs de type date ou heure devraient respecter l'un des formats spécifiés par la RFC 3339, tandis que les durées devraient respecter la norme ISO 8601.

Enveloppe

Il arrive parfois de rencontrer des réponses JSON enveloppées dans un attribut :

{
"result": {
"firstname": "john",
"lastname": "doe"
}
}

La justification d'une telle approche serait de faciliter l'ajout éventuel, plus tard, de méta données sans affecter la partie "données" :

{
"result": {
"firstname": "john",
"lastname": "doe"
},
"created": "01/02/2016"
}
devraitIl est plus efficient de privilégier une structure simple répondant directement au besoin, quitte à la faire évoluer (les schémas JSON le supportent généralement) :
{
"firstname": "john",
"lastname": "doe",
"created": "01/02/2016"
}

Le fait d'envelopper les données permet par exemple de répondre aux contraintes de JSONP : c'est un cas particulier.

Le cas où l'on souhaite proposer une pagination est aussi une situation fréquente d'utilisation d'une enveloppe, pour séparer les éléments de pagination des données; là encore il existe aujourd'hui des meilleures façons d'implémenter la pagination et éviter les enveloppes.

devrait Dans le cas où la réponse est un tableau, les extensions de schémas sont rendues délicates, c'est la bonne situation pour utiliser une enveloppe, de cette manière on a toujours un JSON qui représente un objet (donc extensible).