Apakah boleh mengembalikan HTML dari API JSON?

25

Pada proyek saya saat ini, saya bertanggung jawab untuk implementasi layanan yang melibatkan konsumsi API tenang yang baru dibuat, didokumentasikan sebagai semata-mata mendukung JSON.

Klien secara konsisten membuat permintaan dengan tajuk terima 'aplikasi / json' dan tipe konten 'aplikasi / json'. Namun beberapa titik akhir mengirim respons dengan jenis konten HTML, bahkan badan HTML. Bagi saya ini jelas pendekatan yang salah dan tidak pernah bisa dibenarkan.

Sepanjang proyek, praktik yang sama ini telah diterapkan di dua vendor yang berbeda dan dua layanan yang berbeda. Saya menemukan diri saya harus membenarkan mengapa layanan perlu diubah. Vendor menyatakan bahwa klien harus mengatasi ini dan bahkan perpustakaan pilihan REST saya telah dipertanyakan (RestEasy) karena tidak mengatasinya secara default 'out the box'.

Ini telah menjadi titik frustrasi utama. Saya tidak dapat menemukan banyak referensi untuk mendukung argumen saya, saya berasumsi ini karena intinya diperdebatkan karena begitu jelas.

Pertanyaannya adalah, apakah saya melewatkan sesuatu? Apakah saya menjadi jago tentang hal ini? Apakah boleh menggunakan JSON API yang tidak memiliki tipe konten aplikasi / json dalam skenario ini? Referensi akan dihargai. Bagaimana Anda mengatasi situasi ini dari sudut pandang komersial?

phillip.darley
sumber
1
Menurut tipe konteks maksud Anda header HTTP tipe konten?
Marjan Venema
Ya saya merujuk ke header tipe konten HTTP. Diedit.
phillip.darley
Yah, setidaknya mereka tidak boleh menyebutnya "JSON REST API" ketika itu adalah HTML REST API.
Bergi

Jawaban:

28

Saat Anda mengirim accepttajuk yang meminta jenis media tertentu, server tidak boleh mengirim kembali sesuatu yang lain, dan tentunya tidak dengan 200 kode status OK

Dari Restpatterns.org :

Jika tidak ada bidang tajuk terima, maka diasumsikan bahwa klien menerima semua jenis media. Jika bidang Terima header ada, dan jika server tidak dapat mengirim respons yang dapat diterima sesuai dengan nilai bidang Terima gabungan, maka server HARUS mengirim respons 406 (tidak dapat diterima).

(Penekanan milikku)

Restpatterns.org mengambil ini dari standar HTTP aktual: Definisi bidang header - Terima

Singkatnya: Anda tidak bertele-tele. Layanan tidak mengikuti standar HTTP jika mereka mengembalikan HTML ketika header accept secara khusus memberitahu mereka untuk kembali application/jsondan tidak ada yang lain.

Marjan Venema
sumber
1
+1. Saya setuju dengan jawaban ini, tetapi sayangnya kata shouldtersebut digunakan berulang kali dalam spesifikasi HTTP. Kami harus memulai petisi online untuk mengubah kata-kata itu must.
Reactgular
3
@MarjanVenema "harus" benar karena di bagian 10 dari rfc yang sama ada catatan: "Server HTTP / 1.1 diizinkan untuk mengembalikan respons yang tidak dapat diterima sesuai dengan header terima yang dikirim dalam permintaan. Dalam beberapa kasus, ini bahkan mungkin lebih baik mengirim respons 406. "
imel96
1
Jika klien meminta sumber daya yang benar-benar tidak memiliki representasi JSON, maka tidak peduli seberapa besar mereka menginginkan JSON, mereka mungkin lebih baik menerima sesuatu yang lain yang pasti; Anda tidak dijamin mendapatkan 406. Yang penting adalah server harus menjelaskan jenis konten tanggapan yang sebenarnya.
Donal Fellows
6
@DonalFellows: Tidak, mereka akan lebih baik diberi tahu tentang apa yang sebenarnya terjadi. Server seharusnya tidak hanya mengirim apa pun kembali yang dianggapnya sesuai, tetapi mengirim respons 406 Tidak dapat diterima seperti yang dinyatakan dalam standar. Ingatlah bahwa ketika klien secara spesifik meminta jenis media dan tidak menentukan fallback apa pun, mungkin tidak ada cara untuk memproses jenis media lainnya.
Marjan Venema
2
@ imel96: fakta bahwa internet tidak pernah ketat adalah apa yang menyebabkan kesulitan dalam mencoba mendukung berbagai browser dan server sekarang dipaksa untuk tetap kompatibel dengan html yang tidak valid karena ada terlalu banyak hal di luar sana (dan sayangnya masih sedang dibuat).
Marjan Venema
9

Apa yang Anda maksud dengan "RESTful JSON API" - Saya pikir masalah pertama di sini adalah bahwa Anda mencampuradukkan konsep (atau mungkin seseorang antara Anda dan rekan teknis Anda di "pemasok" Anda).

API yang tenang (apakah Anda berbicara sama sekali tidak benar-benar berada di level 1 atau sesuatu di level 3 atau di atas, c. Http://martinfowler.com/articles/richardsonMaturityModel.html ) adalah tentang cara Anda berinteraksi dengan API, bukan tentang format konten yang dikirim atau diterima dari. Ini bahkan bukan tentang protokol atau mekanisme transportasi ...

Demikian pula JSON API adalah API yang mendukung penggunaan JSON sebagai format data - itu mungkin atau mungkin tidak nyenyak, itu mungkin atau mungkin tidak diimplementasikan menggunakan HTTP dan (dan ini adalah titik kunci) itu mungkin atau mungkin tidak mendukung JSON khusus.

Sebuah baik API berjalan melalui HTTP (yang masuk akal untuk mengasumsikan bahwa dalam konteks Anda sedang berbicara tentang api terbuka melalui HTTP) harus memungkinkan Anda untuk konten permintaan dalam berbagai format dan format tersebut dapat (dan mungkin harus) termasuk HTML serta JSON dan XML. Mengapa? Yah itu akan membuat belajar API jauh lebih mudah, secara konseptual menyediakan UX berbasis browser instan untuk tujuan apa pun dan seterusnya ...

Pertanyaan yang menarik kemudian menjadi apakah API saya, yang mendukung berbagai format konten, dipanggil tanpa diberitahu format apa yang diharapkan klien maka format apa yang harus dikembalikan ...? Ini cenderung ke arah argumen keagamaan - tetapi HTML memberi penyedia pilihan untuk memasukkan informasi bermanfaat (seperti "ingat untuk mengatur konten yang menerima tajuk").

Untuk menjawab pertanyaan sebuah API, yang tenang dan yang mendukung json harus benar-benar dapat mengembalikan HTML jika itu adalah konten yang diminta.

Murph
sumber
1
Saya mengambil kedua poin Anda dan telah mengedit pertanyaan saya. Fakta bahwa layanan ini tenang tidak relevan dan saya telah merinci bahwa klien menerima 'aplikasi / json' di setiap permintaan.
phillip.darley
Saya akan mengatakan bahwa "RESTful JSON API" memiliki arti yang sangat jelas.
gnasher729
1
Saya akan mengatakan bahwa guru saya berusaha keras untuk memastikan kami mengerti mengapa "tidak pernah berasumsi" adalah bagian penting dari menjadi programmer yang baik
Murph
5

Klien secara konsisten membuat permintaan dengan tajuk terima 'aplikasi / json' dan tipe konten 'aplikasi / json'

Ya, ini adalah hal yang benar untuk dilakukan, tetapi tidak berarti vendor peduli. Meskipun saya benar-benar memahami rasa frustrasi Anda, karena saya juga berpikir layanan JSON harus selalu memberikan respons JSON tetapi ada banyak contoh di mana bukan itu masalahnya.

Sepanjang proyek, praktik yang sama ini telah diterapkan di dua vendor yang berbeda dan dua layanan yang berbeda. Saya menemukan diri saya harus membenarkan mengapa layanan perlu diubah. Vendor menyatakan bahwa klien harus mengatasi ini dan bahkan perpustakaan pilihan REST saya telah dipertanyakan (RestEasy) karena tidak mengatasinya secara default 'out the box'.

Saya harus setuju dengan vendornya. Ini adalah layanan mereka dan selama mereka mendokumentasikan dengan jelas kasus khusus untuk menggunakannya, maka Anda tidak dapat benar-benar memaksakan bahwa mereka mengubahnya. Ini kerugian bagi mereka karena pengembang akan lambat untuk mengadopsi API mereka, dan jika mereka mendengarkan apa yang dibutuhkan pengembang maka mereka akan mengubahnya, tetapi sayangnya tidak ada aturan bahwa mereka harus mengikuti standar.

Pertanyaannya adalah apakah saya melewatkan sesuatu?

Tajuk permintaan tidak berarti apa-apa kecuali mereka terganggu dengan benar di ujung yang lain. Saya tahu bahwa jika saya mengembangkan API web menggunakan PHP, maka persetan dengan header permintaan. Saya dapat menanggapi dengan apa pun yang saya inginkan. Sedangkan, layanan yang dikonfigurasi dalam IIS dengan C # menawarkan penanganan header permintaan yang lebih mudah, jenisnya, dan penanganan jenis respons. Ini banyak hubungannya dengan alat yang digunakan vendor untuk membangun API.

Saya menjadi pedantic tentang ini?

Ya dan Tidak. Saya memiliki teman pengembang yang tidak dapat melewati ini. Mereka akan menjadi sangat terpaku oleh masalah dan tidak dapat melanjutkan dengan tugas-tugas lain sampai API bekerja seperti yang mereka harapkan berfungsi. Nah, itu sudah menjadi terlalu mahal.

Ini masalah karena vendor telah menciptakan "lebih banyak pekerjaan" untuk menyelesaikan tugas Anda. Siapa pun akan frustrasi dengan itu. Saya tahu saya akan menjadi.

Apakah boleh menggunakan JSON API yang tidak memiliki tipe konten aplikasi / json dalam skenario ini?

Tentu saja, tapi itu bukan praktik yang baik.

Klien hanya bisa memberi tahu server apa jenis konteksnya request. Itu tidak memiliki kemampuan untuk menegakkan tipe konten untuk response. Klien hanya dapat memberi tahu server bahwa ia akan acceptmengumpulkan jenis-jenis konten yang mungkin.

Definisi Field Header

Bidang Terima header permintaan dapat digunakan untuk menentukan jenis media tertentu yang dapat diterima untuk respons. Header penerimaan dapat digunakan untuk menunjukkan bahwa permintaan secara khusus terbatas pada serangkaian kecil jenis yang diinginkan, seperti dalam kasus permintaan untuk gambar in-line.

Mungkin saja bagi klien untuk meminta gambar image/jpeg, tetapi server merespons dengan text/htmldan kode status 404jika gambar itu tidak ditemukan. Server juga dapat merespons secara tidak benar. Ada banyak situs web Wordpress di luar sana yang merespons text/htmldan kode status 200untuk file yang tidak ditemukan halaman.

Nah, itu semua praktik BAD pada server. Apa yang saya coba katakan kepada Anda adalah bahwa itu benar-benar mungkin, dan sering terjadi. Orang tidak tahu apa yang mereka lakukan ketika mereka mengkonfigurasi hal-hal ini.

Referensi akan dihargai. Bagaimana Anda mengatasi situasi ini dari sudut pandang komersial?

Saya mengalami masalah ini pada beberapa proyek. Anda postdata JSON ke server dan itu memberikan kembali respons JSON atau HTML.

Ini benar-benar bukan masalah besar untuk mengetahui tipe mana yang ada dalam respons. Jika karakter pertama adalah {atau [Anda dapat mengasumsikan JSON. Jika itu <Anda dapat menganggap HTML. Begitulah cara saya menanganinya di masa lalu. Terkadang programmer yang menulis API tahu semua tentang HTTP header. Semuanya kembali sebagai text/htmltanggapan. Jika Anda beruntung, mereka telah mengkonfigurasi Apache ke default text/plainyang kadang-kadang dapat membantu.

Masalah-masalah ini ada dan akan terus ada jauh di masa depan. Komunikasi server ke server sejauh ini merupakan kegiatan yang tidak diatur. Tidak ada badan pengelola yang akan menendang keluar vendor dari serikat pekerja untuk server yang memberikan respons HTTP buruk.

Reactgular
sumber
Ini sesuai dengan jawaban @Marjan Venema tetapi poin kunci lain yang Anda ajukan adalah dokumentasi perilaku ini. Untuk menambah frustrasi saya, vendor belum mendokumentasikan perilaku ini. Jenis konten bervariasi tergantung pada keadaan sesi, namun hanya respons JSON yang didokumentasikan.
phillip.darley