API tenang dan i18n: bagaimana merancang respons?

15

Kami sedang merancang API yang tenang yang terutama dimaksudkan untuk memenuhi kebutuhan satu klien. Karena keadaannya yang sangat khusus, klien ini harus membuat sesedikit mungkin permintaan.

API menangani i18n melalui header Bahasa Terima dalam permintaan. Ini berfungsi untuk semua hal yang perlu dilakukan klien kecuali untuk satu fitur, di mana klien perlu menyimpan respons permintaan ke titik akhir tunggal di semua lokal yang tersedia.

Bisakah kita mendesain API dengan cara yang memungkinkan klien untuk mengambil semua informasi ini dengan satu permintaan dan tanpa melanggar desain RESTful API yang konsisten dan terstruktur dengan baik?

Opsi yang kami pertimbangkan sejauh ini:

  • Mengizinkan penyertaan beberapa lokal di header Bahasa Terima dan menambahkan versi lokal untuk semua lokal yang diminta dalam respons, masing-masing diidentifikasi dengan kode bahasa ISO 639-1 sebagai kuncinya.
  • Membuat sesuatu seperti parameter "? All_languages ​​= true" ke titik akhir itu dan mengembalikan versi lokal untuk semua lokal yang tersedia di respons jika parameter itu ada.
  • (Jika tidak ada di atas yang berfungsi bagi kami) membuat beberapa permintaan untuk mengambil semua versi lokal dari klien.

Mana yang merupakan alternatif terbaik?

AMM
sumber

Jawaban:

22

Anda telah menjelaskan dua cara efektif untuk meminta berbagai bahasa. Baik harus bekerja dengan baik. Saya akan memilih parameter permintaan bahasa eksplisit untuk kode saya sendiri.

TL; DR Backstory

Ada tajuk Terima-Bahasa . Perhatikan, Accepttidak Accepted. Ini adalah bagian standar dari negosiasi konten HTTP. Respons biasanya mengatur header Konten-Bahasa kembali.

Accept-Languageadalah tawaran pembuka, menawarkan serangkaian opsi; Content-Languageadalah resolusi, yang menyatakan bahasa apa yang dipilih. Sebagian besar Content-Languagejawaban mengembalikan satu bahasa, tetapi ada opsi untuk memberikan daftar bahasa respons yang dipisahkan koma. Biasanya itu adalah konten campuran, tetapi tidak ada alasan itu tidak bisa menandakan beberapa alternatif yang terpisah. Jika Anda ingin klien meminta semua bahasa yang tersedia, sudah ada opsi permintaan wildcard *,.

Jadi sudah ada mekanisme tajuk HTTP yang bisa Anda gunakan. Namun, berhati-hatilah bahwa Anda akan mendukung proses negosiasi yang lebih sering menghadirkan berbagai opsi yang mungkin, dan mendapatkan kembali satu opsi. Anda akan mengubah pengertian menjadi "ini daftar opsi, beri saya semua!" Jika Anda setuju dengan itu, Anda punya solusinya.

Namun, ada perdebatan besar tentang kesesuaian menandakan parameter REST API di header HTTP. Ini seperti memasuki restoran dan menyampaikan pesanan terperinci Anda kepada tuan rumah atau lebih daripada menunggu pelayan atau pelayan muncul. Ini dapat bekerja, dan mungkin bekerja dengan baik misalnya jika pesanan yang diarahkan pada tuan rumah berkaitan dengan minuman atau makanan pembuka - hal-hal yang tuan rumah dapat dengan cepat melihat, atau dengan cepat berkomunikasi ke server Anda. Tapi itu juga bisa dilihat sebagai pelanggaran protokol, ditujukan pada level / layer yang salah atau ke pemain yang salah.

Alternatif kedua adalah parameter permintaan eksplisit. Anda menyarankan ?all_languages=true. Itu sepertinya terlalu spesifik. Sesuatu seperti lang=en,fr,es(izinkan beberapa bahasa terdaftar) atau lang=*atau lang=all(tentukan setiap bahasa yang tersedia) tampaknya lebih umum. Ini dapat diungkapkan baik di URL atau badan permintaan.

Apa pun itu, respons multi-bahasa Anda dapat dengan mudah disandikan ke muatan JSON yang dikembalikan:

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

Pada akhirnya, salah satu dari pendekatan ini akan bekerja dengan baik untuk Anda. Keduanya dapat dipandang sebagai "desain RESTful API yang konsisten dan terstruktur dengan baik." Penentuan mana yang lebih baik sebagian besar terletak pada sikap Anda terhadap kesesuaian dukungan (dan sedikit mengubah rasa khas) header negosiasi konten HTTP.

Preferensi saya sendiri adalah untuk tidak mencampurkan header dan parameter lainnya sebagai bagian yang sama dari permintaan API. Parameter eksplisit langatau languagetampaknya lebih bersih bagi saya. Tapi karena HTTP kata kerja (misalnya GET, PUT, POST, PATCH, ...) adalah bagian dari header, dan juga penting untuk / bercampur dengan penafsiran permintaan, saya akui amplop vs isinya perbedaan adalah buatan bit dan kabur. Seperti kebanyakan keputusan desain, para ahli asli menjawabnya secara berbeda, dan YMMV.

Jonathan Eunice
sumber
Respons mereka sangat mendidik dan informatif. Terima kasih. Terima kasih juga untuk memperhatikan hal Terima-tidak-Diterima. Itu benar dalam kode kita, tetapi kemudian saya gagal menggunakan istilah yang tepat saat menulis posting. Saya akan memodifikasinya untuk referensi lebih lanjut.
AMM