Cara menulis API yang buruk

Tuliskan kode seolah-olah itu akan disertai oleh psikopat kejam yang tahu di mana Anda tinggal.


Halo semuanya!


Saya bekerja sebagai pemimpin tim tim Pengembangan Integrasi dalam layanan reservasi hotel online Ostrovok.ru dan hari ini saya ingin berbagi pengalaman saya dengan berbagai API.



Sebagai pengembang sistem yang bekerja dengan penyedia eksternal, saya sering menjumpai berbagai API - yang paling sering adalah SOAP / REST atau sesuatu yang serupa dengan mereka. Namun, bekerja dengan banyak dari mereka meninggalkan kesan bahwa mereka ditulis, tidak dipandu oleh aturan teknis atau akal sehat - seolah-olah dari buku "Bad Advice" oleh Grigory Oster. Pada artikel ini saya akan mencoba untuk menggambarkan kasus-kasus seperti dalam gaya "saran buruk" dan mempertimbangkan contoh-contoh yang berkaitan dengan XML. Komentar dan diskusi dipersilakan.


Latar belakang sejarah

SOAP (dari bahasa Inggris. Simple Object Access Protocol - protokol sederhana untuk mengakses objek) - protokol untuk bertukar pesan terstruktur dalam lingkungan komputasi terdistribusi. SOAP awalnya ditujukan terutama untuk mengimplementasikan panggilan prosedur jarak jauh (RPC). Sekarang protokol digunakan untuk bertukar pesan sewenang-wenang dalam format XML, dan bukan hanya untuk prosedur panggilan.


Pergi ke contoh


1. Melewati xml ke url


Apa yang paling diinginkan pengguna API? Tentu saja, kesederhanaan, keandalan, dan keringkasan. Jadi jangan baca badan permintaan, tetapi terima XML sebagai informasi yang dikodekan url sebagai parameter dari jalur permintaan! Apa yang bisa lebih baik:


http://exapmple.com/xml/form.jsp?RequestName%3DHotelRequest2%26XML%3D%3C%3Fxml%2Bversion%3D%221.0%22%2Bencoding%3D%22UTF-8%22%3F%3E%0A%3CHotelRequest2%2BBuyerId%3D%22test%22%2BUserId%3D%22test%22%2BPassword%3D%22test%22%2BLanguage%3D%22en%22%2BHotel%3D%22-100%22%2BProductCode%3D%221--%22%2BArrivalDate%3D%2223.12.2018%22%2BDepartureDate%3D%2224.12.2018%22%2BArrivalTime%3D%22%22%2BDepartureTime%3D%22%22%2BCurrency%3D%222%22%2BWhereToPay%3D%223%22%2BNumberOfGuests%3D%220%22%2BNumberOfExtraBedsAdult%3D%220%22%2BNumberOfExtraBedsChild%3D%220%22%2BNumberOfExtraBedsInfant%3D%220%22%2B%2F%3E 

Semuanya menjadi sederhana, dan tidak perlu mengurangkan beberapa badan dari kueri - Anda tidak pernah tahu masalah apa yang mungkin ada dengannya.


Spoiler

Saya tidak tahu mengapa ini dilakukan. Masalahnya di sini adalah sebagai berikut: banyak server memiliki batas pada panjang jalur permintaan yang dapat melewatinya. Jika XML besar dalam volume data, maka Anda bisa menyebabkan kesalahan 413 Entitas Terlalu Besar sebagai salah satu skenario. Selain itu, jumlah informasi meningkat, karena kami melakukan penyandian-url sebelum mengirim.


2. Transfer informasi melalui objek data yang bersarang secara berlebihan


Mari kita pikirkan bagaimana membuat informasi dalam jawaban sesulit mungkin? Mari kita gunakan struktur bersarang, dan bahkan dalam format berbeda! Tidak lebih cepat dikatakan daripada dilakukan -


 <Request> <InnerRequest> <RQ>[{"someInfo":"base64Data"}] </RQ> </InnerRequest> </Request> 

Memang, xml tingkat atas, di dalamnya adalah xml lain, dan di dalamnya adalah json, di mana data disajikan di base64, dan lagi json di dalamnya, dan itu sudah akan berisi informasi yang kita butuhkan! Sebuah solusi hebat, hampir seperti dongeng tentang kematian Koshchei, tersembunyi di dalam telur.


Spoiler

Salah satu kelemahan yang paling nyata adalah perlambatan dalam mem-parsing respons sampai semua struktur bersarang dilewatkan, dan setelah itu mungkin ternyata kode kesalahan ditransfer dalam json, bukan pada level yang lebih tinggi. Saya mengerti bahwa penyandian data biner di base64 di dalam xml / json adalah praktik umum, tetapi penyandian format yang berbeda di dalam format lain sudah melampaui kebaikan dan kejahatan.


3. Menambahkan informasi yang tidak terkait dengan data permintaan dan tidak valid dalam format data


Misalkan XML datang kepada kami di badan permintaan, kami memprosesnya dan memberikan jawaban. Terlihat terlalu rumit untuk sistem yang dirancang dengan baik dan sarat muatan. Mari mewajibkan pengguna untuk mengirim tipe data di badan permintaan. Bagaimana cara melakukannya? Tepat di badan permintaan, tentu saja.


 XML= <Request> ... </Request> 

Sedemikian sederhana, kita akan selalu tahu bahwa kami menerima permintaan dalam format XML.


Spoiler

Ternyata kita harus menambahkan lebih banyak byte terkemuka ke badan permintaan yang sudah terbentuk dan hanya setelah itu dimungkinkan untuk membuat permintaan. Beruntung jika Anda tidak perlu mengubah byte terkemuka tergantung pada jenis data permintaan. Dalam hal ini, akan lebih baik menggunakan http Header untuk menunjukkan tipe data, dan tidak mengubah badan permintaan.


4. Duplikasi data tanpa perlu


Misalkan kita memiliki informasi yang sangat, sangat penting dalam struktur respons XML. Bagaimana cara menunjukkan ini kepada pengguna? Yang paling jelas - mari kita tunjukkan beberapa kali sebagai bagian dari jawaban, maka dia pasti akan memperhatikannya.


 <Response> <Obj Info="Important"> <ObjSetting Info="Important"/> <Name>SomeName</Name> <Info>Important</Info> </Obj> </Response> 

Setelah itu, pengguna akhir pasti akan memperhatikan bidang Info.


Spoiler

Dalam hal ini, saya memikirkannya dan bahkan bertanya kepada perusahaan yang menyediakan API tentang arti bidang Info dan apakah informasi dalam tag pada tingkat yang berbeda akan berbeda. Jawabannya adalah: tidak, tidak akan - mereka saling menduplikasi. Mengapa menyesatkan pengguna dan membuat jawabannya lebih sulit jika ini tidak perlu?


5. Melewati parameter dari jenis yang sama secara individual, bukan array


Di salah satu API yang kami gunakan untuk mencari hotel, ada bidang yang menunjukkan usia tamu. Format presentasi apa yang paling baik digunakan untuk menyampaikan informasi ini? Biarkan formatnya seperti ini: setiap usia akan menjadi tag XML wajib yang terpisah, dan kami akan menganggap nilai 0 sebagai tidak adanya parameter ini.


 <Request> <Age1>20</Age> <Age2>20</Age> <Age3>0</Age> <Age4>0</Age> </Request> 

Spoiler

Ada beberapa masalah di sini sekaligus: tidak dapat diperpanjang, informasi yang berlebihan, di samping itu, usia dapat benar-benar nol jika para tamu adalah anak-anak yang baru lahir. Dalam hal ini, Anda perlu menggunakan array, bukan tag yang diberi nama unik.


6. Meneruskan informasi dari permintaan sebelumnya sebagai bagian dari rantai panggilan API


Sudah waktunya untuk memikirkan keamanan API kami. Bagaimana kami memahami bahwa pengguna menerima informasi dari jawaban kami sebelumnya? Biarkan dia mengirimkan jawaban kita, tentu saja!


 <Request> <RequestInfo/> <PreviosResp> ... </PreviosResp> </Request> 

Spoiler

Untuk terus bekerja dengan API, perlu untuk mengirim seluruh respons sistem eksternal dari langkah-langkah sebelumnya dari API, dan bukan beberapa data penting darinya, atau bahkan hash yang pasti akan sesuai dengan jawaban ini. Kelebihan data dengan segala kejayaannya.


7. Jangan gunakan penanda kesalahan yang terjadi, seperti tag kesalahan atau kode http


Kami membuat API kami yang indah dan memperkenalkannya kepada dunia. Tapi begitu ada yang tidak beres, dan kami tidak dapat merumuskan respons kepada pengguna karena kesalahan internal. Apa yang harus dilakukan dalam kasus ini? Berikan templat respons, tanpa data, tanpa kode kesalahan atau informasi lainnya. Tidak seorang pun harus tahu bahwa API ideal kami terkadang tidak berfungsi!
Contoh jawaban seperti itu:


 <Response> <ImportantInfo/> </Response> 

- dengan kode respons 200 OK.


Spoiler

Membuat kesalahan yang dibuat adalah praktik yang sangat buruk. Masalahnya adalah segala sesuatu tampak seolah-olah tidak ada masalah dalam jawaban: tidak ada <Error> , status http mengatakan bahwa semuanya beres. Dalam hal ini, perlu untuk melakukan validasi tambahan atas informasi yang diterima sehingga tidak ada konsekuensi yang tidak terduga dalam sistem kami.


Kesimpulan
Meskipun sejumlah besar dokumentasi tentang bekerja dengan teknologi SOAP / XML dan desain API, banyak masalah masih relevan, dan beberapa solusi bertentangan dengan akal sehat. Saya berharap bahwa dengan artikel ini saya akan dapat menarik perhatian pengembang untuk bukan pendekatan yang paling sukses untuk mengurangi jumlah mereka di masa depan.

Source: https://habr.com/ru/post/id445346/


All Articles