Pertama
Per RFC 3986 §3.4 (Uniform Resource Identifiers § (Komponen Sintaks) | Query
3.4 Permintaan
Komponen kueri berisi data non-hierarkis yang, bersama dengan data dalam komponen jalur (Bagian 3.3), berfungsi untuk mengidentifikasi sumber daya dalam lingkup skema URI dan otoritas penamaan (jika ada).
Komponen permintaan adalah untuk pengambilan data non-hierarkis; ada beberapa hal yang lebih hierarkis daripada pohon keluarga! Ergo - terlepas dari apakah Anda menganggapnya "REST-y" atau tidak - agar sesuai dengan format, protokol, dan kerangka kerja dari dan untuk mengembangkan sistem di internet, Anda tidak boleh menggunakan string kueri untuk mengidentifikasi informasi ini.
REST tidak ada hubungannya dengan definisi ini.
Sebelum menjawab pertanyaan spesifik Anda, parameter kueri "pencarian" Anda tidak bernama. Lebih baik memperlakukan segmen kueri Anda sebagai kamus pasangan nilai kunci.
String kueri Anda dapat lebih tepat didefinisikan sebagai
?first_name={firstName}&last_name={lastName}&birth_date={birthDate}
dll.
Untuk menjawab pertanyaan spesifik Anda
1) Desain API mana yang lebih tenang, dan mengapa? Semantik, mereka berarti dan berperilaku dengan cara yang sama. Sumber daya terakhir di URI adalah "anak-anak", secara efektif menyiratkan bahwa klien beroperasi pada sumber daya anak-anak.
Saya tidak berpikir ini jelas seperti yang Anda yakini.
Tidak ada antarmuka sumber daya ini yang tenang. The utama prasyarat untuk gaya arsitektur tenang adalah bahwa transisi Aplikasi Negara harus dikomunikasikan dari server sebagai hypermedia. Orang-orang telah bekerja keras dalam struktur URI untuk menjadikan mereka entah bagaimana "URI ISTIRAHAT" tetapi literatur formal mengenai REST sebenarnya tidak banyak bicara tentang ini. Pendapat pribadi saya adalah bahwa banyak dari meta-informasi yang salah tentang REST diterbitkan dengan maksud untuk menghancurkan kebiasaan lama yang buruk. (Membangun sistem yang benar-benar "TENANG" sebenarnya cukup banyak pekerjaan. Industri ini beralih ke "REST" dan mengisi kembali beberapa kekhawatiran ortogonal dengan kualifikasi dan pembatasan yang tidak masuk akal.)
Apa yang dikatakan literatur REST adalah bahwa jika Anda akan menggunakan HTTP sebagai protokol aplikasi Anda, Anda harus mematuhi persyaratan formal spesifikasi protokol dan Anda tidak dapat "membuat http saat Anda pergi dan masih menyatakan bahwa Anda menggunakan http" ; jika Anda akan menggunakan URI untuk mengidentifikasi sumber daya Anda, Anda harus mematuhi persyaratan formal spesifikasi tentang URI / URL.
Pertanyaan Anda ditanggapi langsung oleh RFC3986 §3.4, yang telah saya tautkan di atas. Intinya dalam hal ini adalah bahwa meskipun URI yang sesuai tidak cukup untuk mempertimbangkan API "TENANG", jika Anda ingin sistem Anda benar - benar menjadi "TENANG" dan Anda menggunakan HTTP dan URI, maka Anda tidak dapat mengidentifikasi data hierarkis melalui string kueri karena:
3.4 Permintaan
Komponen kueri berisi data non-hierarkis
... sesederhana itu.
2) Apa pro dan kontra untuk masing-masing dalam hal pemahaman dari perspektif klien, dan rawatan dari perspektif desainer.
"Pro" dari dua yang pertama adalah bahwa mereka berada di jalan yang benar . "Kontra" dari yang ketiga adalah tampaknya keliru.
Sejauh menyangkut pengertian Anda dan kemampuan pemeliharaan, hal itu pasti subyektif dan tergantung pada tingkat pemahaman pengembang klien dan potongan desain dari perancang. Spesifikasi URI adalah jawaban pasti tentang bagaimana URI seharusnya diformat. Data hierarkis seharusnya diwakili di jalur dan dengan parameter jalur. Data non-hierarkis seharusnya diwakili dalam kueri. Fragmen ini lebih rumit, karena semantiknya bergantung secara khusus pada jenis media dari representasi yang diminta. Jadi untuk mengatasi komponen "dapat dimengerti" dari pertanyaan Anda, saya akan mencoba menerjemahkan dengan tepat apa yang sebenarnya dikatakan oleh dua URI pertama Anda. Lalu, saya akan mencoba untuk mewakili apa yang Anda katakan ingin Anda capai dengan URI yang valid.
Menerjemahkan URI kata demi kata Anda ke makna semantik mereka
/myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}
Ini mengatakan untuk orang tua kakek nenek, temukan anak mereka memiliki search={text}
Apa yang Anda katakan dengan URI Anda hanya masuk akal jika mencari saudara kandung kakek-nenek. Dengan "kakek-nenek, orang tua, anak-anak" Anda menemukan "kakek-nenek" naik satu generasi ke orang tua mereka dan kemudian kembali ke generasi "kakek-nenek" dengan melihat anak-anak orang tua.
/myservice/api/v1/parents/{parentID}/children?search={text}
Ini mengatakan bahwa untuk induk yang diidentifikasi oleh {parentID}, cari anak mereka memiliki ?search={text}
ini. Ini lebih dekat untuk mengoreksi apa yang Anda inginkan, dan mewakili hubungan orangtua-> anak yang mungkin dapat digunakan untuk memodelkan seluruh API Anda. Untuk memodelkannya dengan cara ini, beban ditempatkan pada klien untuk mengenali bahwa jika mereka memiliki "kakek-nenek", bahwa ada lapisan tipuan antara ID yang mereka miliki dan bagian dari grafik keluarga yang ingin mereka lihat. Untuk menemukan "anak" oleh "kakek-nenek", Anda dapat menghubungi /parents/{parentID}/children
layanan Anda dan kemudian memeriksa anak yang dikembalikan, cari anak-anak mereka untuk pengidentifikasi orang Anda.
Implementasi persyaratan Anda sebagai URI.
Jika Anda ingin memodelkan pengenal sumber daya yang lebih dapat dikembangkan yang dapat berjalan di atas pohon, saya dapat memikirkan beberapa cara untuk mencapai itu.
1) Yang pertama, saya sudah singgung. Mewakili grafik "Orang" sebagai struktur komposit. Setiap orang memiliki referensi ke generasi di atasnya melalui jalur Orang Tua dan ke generasi di bawahnya melalui jalur Anak-anaknya.
/Persons/Joe/Parents/Mother/Parents
akan menjadi cara untuk mengambil kakek dari pihak ibu Joe.
/Persons/Joe/Parents/Parents
akan menjadi cara untuk mengambil semua kakek-nenek Joe.
/Persons/Joe/Parents/Parents?id={Joe.GrandparentID}
akan mengambil kakek Joe memiliki pengenal yang Anda miliki.
dan ini semua masuk akal (perhatikan bahwa mungkin ada penalti kinerja di sini tergantung pada tugas dengan memaksa dfs di server karena kurangnya identifikasi cabang dalam pola "Orang Tua / Orang Tua / Orangtua".) Anda juga mendapat manfaat dari memiliki kemampuan untuk mendukung sejumlah generasi yang sewenang-wenang. Jika, karena alasan tertentu, Anda ingin melihat 8 generasi, Anda dapat mewakili ini sebagai
/Persons/Joe/Parents/Parents/Parents/Parents/Parents/Parents/Parents/Parents?id={Joe.NotableAncestor}
tetapi ini mengarah ke opsi dominan kedua untuk mewakili data ini: melalui parameter jalur.
2) Gunakan parameter jalur untuk "kueri hierarki" Anda bisa mengembangkan struktur berikut untuk membantu meringankan beban konsumen dan masih memiliki API yang masuk akal.
Untuk melihat kembali ke 147 generasi, mewakili pengidentifikasi sumber daya ini dengan parameter jalur memungkinkan Anda melakukannya
/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor}
Untuk menemukan Joe dari kakek-nenek buyutnya, Anda dapat melihat ke bawah grafik sejumlah generasi yang dikenal untuk Joe's Id.
/Persons/JoesGreatGrandparent/Children;generations=3?id={Joe.Id}
Hal utama yang perlu diperhatikan dengan pendekatan ini adalah bahwa tanpa informasi lebih lanjut dalam pengidentifikasi dan permintaan, Anda harus berharap bahwa URI pertama adalah mengambil Orang 147 generasi dari Joe dengan pengidentifikasi Joe.NotableAncestor. Anda harus mengharapkan yang kedua untuk mengambil Joe. Asumsikan bahwa apa yang sebenarnya Anda inginkan adalah klien panggilan Anda untuk dapat mengambil seluruh rangkaian node dan hubungan mereka antara Person root dan konteks akhir URI Anda. Anda dapat melakukannya dengan URI yang sama (dengan beberapa hiasan tambahan) dan mengatur Penerimaan text/vnd.graphviz
atas permintaan Anda, yang merupakan jenis media terdaftar IANA untuk .dot
representasi grafik. Dengan itu, ubah URI ke
/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor.Id}#directed
dengan HTTP Request Header
Accept: text/vnd.graphviz
dan Anda dapat meminta klien berkomunikasi dengan cukup jelas bahwa mereka menginginkan grafik arahan hierarki generasi antara Joe dan 147 generasi sebelumnya di mana generasi leluhur ke-147 itu mengandung seseorang yang diidentifikasi sebagai "Nenek Moyang Terkemuka" Joe.
Saya tidak yakin apakah teks / vnd.graphviz memiliki semantik yang telah ditentukan sebelumnya untuk fragmennya; Saya tidak dapat menemukannya dalam pencarian instruksi. Jika jenis media itu memang memiliki informasi fragmen yang telah ditentukan sebelumnya, maka semantiknya harus diikuti untuk membuat URI yang sesuai. Tetapi, jika semantik tersebut tidak ditentukan sebelumnya, spesifikasi URI menyatakan bahwa semantik pengidentifikasi fragmen tidak dibatasi dan sebagai gantinya didefinisikan oleh server, menjadikan penggunaan ini valid.
3) Apa string query yang benar-benar digunakan, selain "pemfilteran" pada sumber daya Anda? Jika Anda pergi dengan pendekatan pertama, parameter filter tertanam dalam URI itu sendiri sebagai parameter jalur, bukan parameter string kueri.
Saya percaya saya sudah benar-benar mengalahkan ini sampai mati, tetapi string kueri bukan untuk sumber daya "penyaringan". Mereka untuk mengidentifikasi sumber daya Anda dari data non-hierarkis. Jika Anda telah menelusuri hierarki Anda dengan jalan Anda dengan pergi
/person/{id}/children/
dan Anda ingin mengidentifikasi anak tertentu atau sekelompok anak tertentu , Anda akan menggunakan beberapa atribut yang berlaku untuk set yang Anda identifikasi dan memasukkannya ke dalam kueri.