RESTful API i i18n: jak zaprojektować odpowiedź?

15

Projektujemy interfejs API RESTful przeznaczony głównie do zaspokojenia potrzeb jednego klienta. Ze względu na bardzo szczególne okoliczności ten klient musi składać jak najmniej zapytań.

Interfejs API obsługuje i18n za pomocą nagłówka Accept-Language w żądaniach. Działa to dla wszystkich rzeczy, które klient musi zrobić, z wyjątkiem jednej funkcji, w której klient musi przechowywać odpowiedzi na żądanie do jednego punktu końcowego we wszystkich dostępnych lokalizacjach.

Czy możemy w jakiś sposób zaprojektować interfejs API w taki sposób, aby klient mógł pobrać wszystkie te informacje za pomocą jednego żądania i bez naruszenia spójnego, dobrze zorganizowanego projektu interfejsu API RESTful?

Opcje, które rozważaliśmy do tej pory:

  • Umożliwienie włączenia wielu ustawień narodowych do nagłówka Accept-Language i dodanie zlokalizowanych wersji dla wszystkich żądanych ustawień narodowych w odpowiedzi, z których każdy jest identyfikowany przez kod języka ISO 639-1 jako klucz.
  • Tworzenie czegoś takiego jak parametr „? All_languages ​​= true” do tego punktu końcowego i zwracanie zlokalizowanych wersji dla wszystkich dostępnych ustawień narodowych w odpowiedzi, jeśli ten parametr jest obecny.
  • (Jeśli żadne z powyższych nie działa dla nas), wysyłanie wielu żądań pobrania wszystkich zlokalizowanych wersji od klienta.

Która jest najlepszą alternatywą?

AMM
źródło

Odpowiedzi:

22

Opisałeś dwa skuteczne sposoby proszenia o wiele języków. Albo powinno działać dobrze. Wybrałbym parametr żądania jawnego języka dla mojego własnego kodu.

TL; DR Backstory

Istnieje nagłówek Accept-Language . Uwaga Acceptnie Accepted. Jest to standardowa część negocjacji treści HTTP. Odpowiedź zwykle przywraca nagłówek języka treści .

Accept-Languageto oferta otwarcia oferująca zestaw opcji; Content-Languageto rozdzielczość określająca, jaki język został wybrany. Większość Content-Languageodpowiedzi zwraca jeden język, ale istnieje możliwość podania listy języków odpowiedzi oddzielonych przecinkami. Zwykle byłaby to treść mieszana, ale nie ma powodu, dla którego nie mogłaby zasygnalizować wielu rozłącznych alternatyw. Jeśli chciał klienta do żądania wszystkie dostępne języki, nie jest już opcja wieloznaczny prośba *.

Istnieje już mechanizm nagłówka HTTP, którego można użyć. Uważaj jednak na to, że będziesz prześladować proces negocjacji, który częściej przedstawia szereg możliwych opcji i zwraca jedną opcję. Zmieniłbyś sens na „tutaj jest lista opcji, daj mi je wszystkie!” Jeśli nie masz nic przeciwko, masz rozwiązanie.

Istnieje jednak poważna debata na temat przydatności sygnalizowania parametrów interfejsu API REST w nagłówkach HTTP. To trochę jak wchodzenie do restauracji i zamawianie szczegółowego zamówienia gospodarzowi lub maître d 'zamiast czekania na pojawienie się kelnera lub kelnerki. Może działać i może działać dobrze, np. Jeśli zamówienie skierowane do gospodarza dotyczy napojów lub przekąsek - rzeczy, które gospodarz może szybko zobaczyć lub szybko komunikować się z serwerem. Ale może to być również postrzegane jako naruszenie protokołu, skierowane do niewłaściwego poziomu / warstwy lub do niewłaściwego odtwarzacza.

Drugą alternatywą byłby jawny parametr żądania. Sugerujesz ?all_languages=true. To wydaje się zbyt szczegółowe. Coś w rodzaju lang=en,fr,es(zezwól na wiele wymienionych języków) lub lang=*lub lang=all(określ każdy dostępny język) wydaje się bardziej ogólne. Można to wyrazić w adresie URL lub treści żądania.

Tak czy inaczej, twoja wielojęzyczna odpowiedź może być łatwo zakodowana w zwrócony ładunek JSON:

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

W końcu jedno z tych podejść powinno być dla Ciebie dobre. Oba mogą być postrzegane jako „spójny, dobrze zorganizowany projekt interfejsu API RESTful”. Ustalenie, która opcja jest lepsza, zależy głównie od twojego nastawienia do stosowności piggybackingu (i nieznacznie zmieniającego typowe poczucie) nagłówków negocjacji treści HTTP.

Moje własne preferencje to nie mieszanie nagłówków i innych parametrów jako równych części żądania API. Wyraźny langlub languageparametr wydaje mi się czystszy. Ale ponieważ HTTP czasownik (np GET, PUT, POST, PATCH, ...) jest częścią nagłówka, a także krytyczne / przemieszane z interpretacją wniosek, przyznaję koperta vs. zawartość rozróżnienie jest nieco sztuczny i rozmyte. Podobnie jak w przypadku większości decyzji projektowych, prawdziwi eksperci odpowiadają na to inaczej, a YMMV.

Jonathan Eunice
źródło
Ich reakcja była bardzo edukacyjna i informacyjna. Dziękuję Ci. Dziękujemy również za zauważenie rzeczy Zaakceptowana. Jest to poprawne w naszym kodzie, ale potem nie użyłem właściwego terminu podczas pisania postu. Zmodyfikuję to dla dalszych odniesień.
AMM