web-dev-qa-db-fra.com

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

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.

Pouvons-nous 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?

15
AMM

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, Accept pas Accepted. C'est une partie standard de la négociation de contenu HTTP. La réponse définit généralement un en-tête Content-Language .

Accept-Language est l'offre d'ouverture, offrant un ensemble d'options; Content-Language est la résolution, indiquant la langue choisie. Plus Content-Language les ré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 vouliez 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 y a, cependant, un débat considérable quant à la pertinence de la signalisation REST Paramètres API dans les en-têtes HTTP. C'est un peu comme entrer dans un restaurant et masquer votre commande détaillée à l'hôte ou au maître d'hôtel plutôt qu'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. peut également être considérée 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=* ou lang=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 de ce qui est le mieux repose principalement sur votre attitude à l'égard de l'adéquation 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. Le paramètre explicite lang ou language me semble plus propre. Mais puisque le verbe HTTP (par exemple GET, PUT, POST, PATCH, ...) fait partie de l'en-tête, et est également critique pour/mêlé à l'interprétation de la demande, j'avoue que la distinction enveloppe/contenu est un peu artificielle et floue. Comme pour la plupart des décisions de conception, les véritables experts y répondent différemment, et YMMV.

23
Jonathan Eunice