API RESTful et i18n: comment concevoir la réponse?

15

Nous concevons une API RESTful qui est principalement destinée à répondre aux besoins d'un seul client. En raison de sa situation très particulière, ce client doit faire le moins de demandes possible.

L'API gère i18n via un en-tête Accept-Language dans les demandes. Cela fonctionne pour tout ce que le client doit faire, à l'exception d'une fonctionnalité, dans laquelle le client doit stocker les réponses d'une demande à un seul point de terminaison dans tous les paramètres régionaux disponibles.

Peut-on en quelque sorte concevoir l'API de manière à permettre au client de saisir toutes ces informations avec une seule demande et sans casser une conception d'API RESTful cohérente et bien structurée?

Options que nous avons envisagées jusqu'à présent:

  • Autoriser l'inclusion de plusieurs paramètres régionaux dans l'en-tête Accept-Language et ajouter des versions localisées pour tous les paramètres régionaux demandés dans la réponse, chacun identifié par son code de langue ISO 639-1 comme clé.
  • Créer quelque chose comme un paramètre "? All_languages ​​= true" sur ce noeud final et renvoyer des versions localisées pour tous les paramètres régionaux disponibles dans la réponse si ce paramètre est présent.
  • (Si rien de ce qui précède ne fonctionne pour nous) faire plusieurs demandes pour récupérer toutes les versions localisées du client.

Laquelle est la meilleure alternative?

AMM
la source

Réponses:

22

Vous avez décrit deux façons efficaces de demander plusieurs langues. Soit devrait bien fonctionner. Je choisirais le paramètre de demande de langage explicite pour mon propre code.

TL; DR Backstory

Il y a un en -tête Accept-Language . Remarque, Acceptnon Accepted. C'est une partie standard de la négociation de contenu HTTP. La réponse rétablit généralement un en - tête Content-Language .

Accept-Languageest l'offre d'ouverture, offrant un ensemble d'options; Content-Languageest la résolution, indiquant quelle langue a été choisie. La plupart des Content-Languageréponses renvoient une seule langue, mais il existe une option pour fournir une liste de langues de réponse séparées par des virgules. Habituellement, ce serait un contenu mixte, mais il n'y a aucune raison qu'il ne puisse pas signaler plusieurs alternatives disjointes. Si vous souhaitez que le client demande toutes les langues disponibles, il existe déjà une option de demande générique,* .

Il existe donc déjà un mécanisme d'en-tête HTTP que vous pouvez utiliser. Cependant, sachez que vous utiliseriez un processus de négociation qui présente le plus souvent un éventail d'options possibles et récupère une seule option. Vous changeriez le sens de "voici une liste d'options, donnez-moi toutes!" Si cela vous convient, vous avez une solution.

Il existe cependant un débat considérable quant à la pertinence de la signalisation des paramètres de l'API REST dans les en-têtes HTTP. C'est un peu comme entrer dans un restaurant et rendre votre commande détaillée à l'hôte ou au maître d'hôtel plutôt que d'attendre que le serveur ou la serveuse apparaisse. Cela peut fonctionner et peut bien fonctionner, par exemple si la commande adressée à l'hôte concerne des boissons ou des amuse-gueules - des choses que l'hôte peut voir rapidement ou communiquer rapidement à votre serveur. Mais cela peut aussi être vu comme une violation de protocole, adressée au mauvais niveau / couche ou au mauvais joueur.

Une deuxième alternative serait un paramètre de requête explicite. Vous suggérez ?all_languages=true. Cela semble trop spécifique. Quelque chose comme lang=en,fr,es(autoriser plusieurs langues répertoriées) ou lang=*oulang=all (spécifier toutes les langues disponibles) semble plus général. Cela peut être exprimé dans l'URL ou dans le corps de la demande.

Dans les deux cas, votre réponse multilingue peut être facilement encodée en charge utile JSON retournée:

[ { "lang": "en", "content": "As Gregor Samsa awoke one morning..." },
  { "lang": "de", "content": "Als Gregor Samsa eines Morgens..." },
  ...
]

En fin de compte, l'une ou l'autre de ces approches devrait vous convenir. L'une ou l'autre pourrait être considérée comme une «conception d'API RESTful cohérente et bien structurée». La détermination quant à ce qui est le mieux repose principalement sur votre attitude envers la pertinence des en-têtes de négociation de contenu HTTP (et en modifiant légèrement le sens typique).

Ma propre préférence est de ne pas mélanger les en-têtes et autres paramètres en tant que parties égales d'une demande d'API. L'explicite langou le languageparamètre me semble plus propre. Mais depuis le HTTP verbe (par exemple GET, PUT, POST, PATCH, ...) fait partie de l' en- tête, et aussi critique pour / entremêlées avec l'interprétation de la demande, je l' avoue l'enveloppe par rapport contenu distinction est un peu artificielle et floue. Comme pour la plupart des décisions de conception, les vrais experts y répondent différemment, et YMMV.

Jonathan Eunice
la source
Leur réponse a été très éducative et informative. Je vous remercie. Merci aussi d'avoir remarqué la chose Accept-not-Accepted. C'est correct dans notre code, mais je n'ai pas réussi à utiliser le terme approprié lors de la rédaction du message. Je vais le modifier pour d'autres références.
AMM