Kapan menggunakan sumber daya bersarang di API yang tenang

16

Saya memiliki dua sumber: pengguna dan tautan.

Pengguna dapat memiliki beberapa tautan yang dikaitkan dengannya. Saya telah merancang API RESTful saya sehingga Anda dapat mencapai tautan yang dikaitkan dengan pengguna di URI berikut:

/users/:id/links

Namun, saya selalu perlu memiliki URI untuk tautan yang adil - terkadang saya mungkin ingin semua tautan, terlepas dari pengguna.

Untuk ini saya punya:

/links

Apakah ini terdengar oke? Memiliki dua URI untuk tautan?

Saya ingin tahu apakah saya seharusnya menjangkau tautan untuk pengguna dengan URI seperti:

/links/user/:id atau /links/?user=:id

Dengan cara ini, saya hanya memiliki satu sumber daya untuk tautan.

Oliver Joseph Ash
sumber
3
hmm .. Yang ini sepertinya lebih elegan:/links/user/:id
theMarceloR
7
@ theMarceloR: Itulah satu-satunya contoh dari tiga yang saya tidak menemukan jelas. Apakah sumber daya untuk tautan atau pengguna? URI jauh lebih tidak ambigu baik menggunakan metode nested resource ( /users/:id/links) atau metode string kueri ( /links/?user=:id) karena sebenarnya adalah query. /links/user/:idmungkin terlihat bagus dan / atau lebih mudah untuk dirutekan dalam beberapa kerangka kerja tetapi sebenarnya cukup membingungkan.
Aaronaught

Jawaban:

16

Tidak, tidak ada yang salah dengan memiliki banyak sumber daya untuk "hal" yang sama, dalam hal ini daftar tautan.

Kami baru-baru ini berjuang dengan masalah yang sama. Keputusan kami adalah untuk memiliki semua sumber daya di mana tidak ada kepemilikan yang ketat untuk tidak disarangkan. Dengan kata lain, tautan akan dimodelkan di bawah

/links -- all links
/links/:linkid -- a particular link

Lalu, filter pada koleksi tautan dinyatakan sebagai parameter kueri. Jadi untuk mendapatkan tautan dari pengguna tertentu, Anda akan menggunakan:

/links?user=/users/:userid

Ini juga memungkinkan komposisi filter lebih mudah:

/links?user=/users/10&since=2013-01-01

Dan mudah dipahami secara konseptual - Anda memiliki koleksi item, dan Anda menambahkan filter padanya.

Yang sedang berkata, tidak ada yang lebih "tenang" tentang pendekatan ini daripada skema penamaan URI lainnya. Itu hanya sebuah konvensi yang kami temukan dapat dibaca manusia dan mudah bagi kami para pengembang untuk memahami dan merangkulnya. REST tidak peduli dengan apa yang Anda masukkan ke pengidentifikasi sumber daya Anda.

waxwing
sumber
1
"Semua sumber daya di mana tidak ada kepemilikan yang ketat untuk tidak disarangkan" terdengar seperti aturan yang baik untuk dimiliki. Terima kasih banyak.
Oliver Joseph Ash
5
Saya akan mengatakan bahwa ada adalah sesuatu yang salah dengan memiliki beberapa sumber daya untuk entitas fisik yang sama, tapi itu tidak benar-benar apa ini. Setiap tautan individu memiliki URL kanonik (tautan /: id), sedangkan setiap sumber daya di atas sebenarnya adalah satu sumber daya (/ tautan) dengan filter yang diterapkan. Juga, saya merasa aneh oleh ?user=users/:useriddi dalam string kueri; apa yang salah dengan adil ?userid=:userid?
Aaronaught
2
@Aaronaught: alasan untuk tetap menggunakan uri dan bukannya ids telanjang adalah agar klien dapat memperlakukan semua pengidentifikasi sumber daya secara setara, yaitu klien hanya perlu tahu bahwa 'pengguna ini diidentifikasi oleh "/*******"; di mana *itu buram. tetapi pengenal yang sama selalu dapat digunakan untuk merujuk ke sumber daya itu (seperti dalam, dengan tautan), untuk mengambil versi terbaru dari sumber daya itu, dan seterusnya. konten uri itu hanya dipahami oleh server asal. Ini juga berarti bahwa jika pengidentifikasi perlu berubah, katakanlah /realm/:businessid/users/:id, klien tidak berubah sama sekali.
SingleNegationElimination
@TokenMacGuy: Maaf, saya tidak mengerti bagian dari komentar Anda. Apa perbedaan praktis antara /users/:userid/linksdan /links?userid=:userid? Dalam kedua kasus, pengidentifikasi tidak berubah, mereka mengambil versi sumber daya saat ini, dan klien memperlakukannya dengan cara yang sama. Tidak ada yang namanya URL kanonik untuk ini karena ini bukan sumber daya, ini kueri, jadi ini hanya dua jenis sintaksis kueri yang berbeda. Saya juga tidak jelas tentang bagaimana klien tidak perlu mengubah jika struktur URL berubah; itu dianggap sebagai perubahan besar dalam REST kecuali 301 ada di tempat.
Aaronaught
1
@Aaronaught: Saya mungkin salah paham tentang kekhawatiran Anda. Misalkan /linksmendukung antarmuka kueri, /links?user=/users/123memungkinkan pendekatan kotak hitam untuk pengidentifikasi sumber daya di klien yang /links?userid=123tidak. yang terakhir mengharuskan klien memahami apa itu userid dan bagaimana cara mendapatkannya, mungkin dari sumber daya yang diperolehnya dari /users/123atau /links/456/user. Yang pertama berarti klien dapat menggunakan uri yang tidak dimodifikasi; seandainya /links/.../usermemberikan respons hypermedia (katakanlah, dengan Location:header).
SingleNegationElimination
1

Jadi kekhawatiran saya adalah: / pengguna /: userid / tautan mengembalikan "tautan", TETAPI jika user_id tidak diidentifikasi, ini akan mengembalikan 404.

Namun

/ links? userid =: userid berpotensi mengembalikan daftar kosong (pada dasarnya 200) yang sebenarnya adalah bug. Dan sangat mungkin.

Meskipun keduanya berfungsi, sarang memberi Anda fungsionalitas tambahan yang nantinya dapat Anda manfaatkan.

Richard Browne
sumber