RESTful API und i18n: Wie gestaltet man die Antwort?

15

Wir entwerfen eine RESTful-API, die hauptsächlich auf die Anforderungen eines einzelnen Clients zugeschnitten ist. 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 Ländereinstellungen speichern muss.

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

Optionen, über die wir bisher nachgedacht 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 bei uns funktioniert) Mehrere Anfragen stellen, um alle lokalisierten Versionen vom Client abzurufen.

Welches ist die beste Alternative?

AMM
quelle

Antworten:

22

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

TL; DR Hintergrundgeschichte

Es gibt einen Accept-Language-Header . Beachten Sie Acceptnicht Accepted. Dies ist ein Standardbestandteil der HTTP-Inhaltsaushandlung. Die Antwort setzt normalerweise einen Content-Language- Header zurück.

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

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

Es gibt jedoch erhebliche Diskussionen über die Eignung der Signalisierung von REST-API-Parametern in HTTP-Headern. Es ist ein bisschen so, als würde man ein Restaurant betreten und dem Wirt oder dem Maître d 'eine detaillierte Bestellung übermitteln, anstatt auf das Erscheinen des Kellners oder der Kellnerin zu warten. Es kann funktionieren und kann auch gut funktionieren, wenn sich die an den Host gerichtete Bestellung auf Getränke oder Vorspeisen bezieht - Dinge, die der Host schnell erledigen oder schnell mit Ihrem Server kommunizieren kann. Es kann aber auch als ein Verstoß gegen das Protokoll angesehen werden, der auf der falschen Ebene / Ebene oder an den falschen Spieler gerichtet ist.

Eine zweite Alternative wäre ein expliziter Anforderungsparameter. Sie schlagen vor ?all_languages=true. Das scheint zu spezifisch. So etwas wie lang=en,fr,es(können mehrere aufgeführten Sprachen) oder lang=*oder lang=all(angeben jede verfügbare Sprache) scheint allgemeiner. Dies kann entweder in der URL oder im Anforderungshauptteil ausgedrückt werden.

In beiden Fällen kann Ihre mehrsprachige Antwort einfach 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, welche besser ist, hängt hauptsächlich von Ihrer Einstellung zur Angemessenheit des Huckepacks von HTTP-Inhaltsverhandlungs-Headern (und einer geringfügigen Änderung des typischen Sinns davon) ab.

Meine eigene Präferenz ist nicht Intermix - Header und andere Parameter als gleichwertige Teile einer API - Anfrage. Der explizite langoder languageParameter scheint mir sauberer. Aber da die HTTP - Verb (zB GET, PUT, POST, PATCH, ...) Teil des Headers ist, und auch kritisch / vermischte mit der Auslegung des Antrags, das gebe ich den Umschlag gegen Inhalt Unterscheidung etwas künstlich ist und unscharf. Wie bei den meisten Designentscheidungen antworten echte Experten anders und YMMV.

Jonathan Eunice
quelle
Ihre Reaktion war sehr lehrreich und informativ. Vielen Dank. Vielen Dank auch für die Kenntnisnahme der Accept-not-Accepted-Sache. Es ist in unserem Code korrekt, aber dann habe ich beim Schreiben des Beitrags nicht den richtigen Begriff verwendet. Ich werde es für weitere Verweise ändern.
AMM