it-swarm.com.de

RESTful API und i18n: Wie gestaltet man die Antwort?

Wir entwickeln eine RESTful-API, die hauptsächlich die Anforderungen eines einzelnen Clients erfüllen soll. Aufgrund seiner besonderen Umstände muss dieser Kunde so wenig Anfragen wie möglich stellen.

Die API verarbeitet i18n über einen Accept-Language-Header in den Anforderungen. Dies funktioniert für alle Aufgaben, die der Client ausführen muss, mit Ausnahme einer Funktion, bei der der Client die Antworten einer Anforderung an einen einzelnen Endpunkt in allen verfügbaren Gebietsschemas speichern muss.

Können wir die API so gestalten, dass der Client alle diese Informationen mit einer einzigen Anforderung abrufen kann, ohne ein konsistentes, gut strukturiertes RESTful-API-Design zu beschädigen?

Optionen, die wir bisher in Betracht gezogen haben:

  • Ermöglichen der Aufnahme mehrerer Gebietsschemas in den Accept-Language-Header und Hinzufügen lokalisierter Versionen für alle angeforderten Gebietsschemas in der Antwort, wobei jedes durch seinen ISO 639-1-Sprachcode als Schlüssel identifiziert wird.
  • Erstellen Sie so etwas wie einen "? All_languages ​​= true" -Parameter für diesen Endpunkt und geben Sie lokalisierte Versionen für alle verfügbaren Gebietsschemas in der Antwort zurück, wenn dieser Parameter vorhanden ist.
  • (Wenn keines der oben genannten Verfahren für uns funktioniert) Mehrere Anfragen stellen, um alle lokalisierten Versionen vom Client abzurufen.

Welches ist die beste Alternative?

15
AMM

Sie haben zwei effektive Möglichkeiten beschrieben, um nach mehreren Sprachen zu fragen. Beides sollte gut funktionieren. Ich würde den expliziten Sprachanforderungsparameter für meinen eigenen Code wählen.

TL; DR Backstory

Es gibt einen Accept-Language-Header . Beachten Sie, Accept nicht Accepted. Dies ist ein Standardbestandteil der Aushandlung von HTTP-Inhalten. Die Antwort setzt normalerweise einen Content-Language -Header zurück.

Accept-Language ist das Eröffnungsgebot, das eine Reihe von Optionen bietet; Content-Language ist die Auflösung, die angibt, welche Sprache gewählt wurde. Die meisten Content-Language Antworten geben eine einzelne Sprache zurück, es besteht jedoch die Möglichkeit, eine durch Kommas getrennte Liste von Antwortsprachen bereitzustellen. Normalerweise wäre das ein gemischter Inhalt, aber es gibt keinen Grund, warum es nicht mehrere disjunkte Alternativen signalisieren könnte. Wenn Sie möchten, dass der Client alle verfügbaren Sprachen anfordert, gibt es bereits die Platzhalteranforderungsoption *.

Es gibt also bereits einen HTTP-Header-Mechanismus, den Sie verwenden können. Beachten Sie jedoch, dass Sie einen Verhandlungsprozess huckepack nehmen, der häufiger eine Reihe möglicher Optionen enthält und eine einzelne Option zurückerhält. Sie würden den Sinn auf "Hier ist eine Liste von Optionen, geben Sie mir alle!" Wenn Sie damit einverstanden sind, haben Sie eine Lösung.

Es gibt jedoch erhebliche Debatten über die Eignung der Signalisierung REST API-Parameter in HTTP-Headern. Es ist ein bisschen so, als würde man ein Restaurant betreten und Ihre detaillierte Bestellung eher an den Host oder den Maître d 'herausplatzen lassen als darauf zu warten, dass der Kellner oder die Kellnerin erscheint. Es kann funktionieren und kann auch gut funktionieren, z. B. wenn sich die an den Gastgeber gerichtete Bestellung auf Getränke oder Vorspeisen bezieht - Dinge, die der Gastgeber schnell erledigen oder schnell mit Ihrem Server kommunizieren kann kann auch als Verstoß gegen das Protokoll angesehen werden, das auf der falschen Ebene/Ebene oder an den falschen Spieler gerichtet ist.

Eine zweite Alternative wäre ein expliziter Anforderungsparameter. Du schlägst vor ?all_languages=true. Das scheint zu spezifisch. Etwas wie lang=en,fr,es (mehrere aufgelistete Sprachen zulassen) oder lang=* oder lang=all (geben Sie jede verfügbare Sprache an) erscheint allgemeiner. Dies kann entweder in der URL oder im Anfragetext ausgedrückt werden.

In beiden Fällen kann Ihre mehrsprachige Antwort problemlos in zurückgegebene JSON-Nutzdaten codiert werden:

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

Am Ende sollte einer dieser Ansätze für Sie gut funktionieren. Beides könnte als "konsistentes, gut strukturiertes RESTful-API-Design" angesehen werden. Die Entscheidung darüber, welche besser ist, beruht hauptsächlich auf Ihrer Einstellung zur Angemessenheit des Huckepack-Gehörs (und zur geringfügigen Änderung des typischen Sinns) von HTTP-Inhaltsverhandlungsheadern.

Ich bevorzuge es, nicht Header und andere Parameter als gleiche Teile einer API-Anfrage zu mischen. Der explizite Parameter lang oder language erscheint mir sauberer. Aber da das HTTP-Verb (z. B. GET, PUT, POST, PATCH, ...) Teil des Headers ist und auch für/kritisch ist Vermischt mit der Interpretation der Anfrage gebe ich zu, dass die Unterscheidung zwischen Umschlag und Inhalt etwas künstlich und unscharf ist. Wie bei den meisten Designentscheidungen antworten echte Experten anders und YMMV.

23
Jonathan Eunice