Mengejar garis miring di API RESTful

60

Saya telah berdebat tentang apa yang harus dilakukan dengan garis miring di API ISTIRAHAT.

Katakanlah saya memiliki sumber daya yang disebut anjing dan sumber daya bawahan untuk masing-masing anjing. Karena itu kami dapat melakukan hal berikut:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

Tetapi apa yang kita lakukan dengan kasus khusus berikut:

GET/PUT/POST/DELETE http://example.com/dogs/

Pandangan pribadi saya adalah ini mengatakan kirim permintaan ke sumber daya anjing individual dengan id = null. Saya pikir API harus mengembalikan 404 untuk kasus ini.

Yang lain mengatakan permintaan tersebut mengakses sumber daya anjing yaitu garis miring trailing diabaikan.

Adakah yang tahu jawaban pasti?

Gaz_Edge
sumber
2
Saya pikir cara Tenang adalah untuk membedakan antara anjing / id dan anjing (artinya semua anjing).
pdr
Dari buku RESTful Web Services - sumber daya bawahan: sumber daya yang ada dalam kaitannya dengan beberapa sumber daya "induk" lainnya yaitu dogs / {id} Basis data yang diaktifkan web dapat mengekspos tabel sebagai sumber daya, dan setiap baris basis data sebagai sumber daya bawahannya .
Gaz_Edge
Ini mengakses sumber daya anjing, garis miring harus diabaikan yang berarti harus mendapatkan respons terlarang untuk mencoba menghapus sesuatu yang tidak boleh diterapkan pada penghapusan. Saya kira 404 juga bisa diterima. Apakah itu penting?
Benjamin Gruenbaum
Saya tidak mengikuti - siapa bilang Anda tidak bisa menghapus anjing? Jika Anda menghapus anjing, itu menghapus dirinya sendiri dan semua anjing individu. Itu sebabnya saya pikir mengizinkan panggilan ke anjing / berisiko. Bagaimana jika klien bermaksud menghapus satu anjing, tetapi secara tidak sengaja meninggalkan {id}. Hasilnya adalah semua anjing akan dihapus. Jauh lebih aman untuk menganggapnya meminta {id} null dan mengembalikan 404
Gaz_Edge
Saya akan memperlakukan dogsdan dogs/setara. Bagi saya jelas itu dogs/adalah direktori yang berisi masing-masing anjing. Itu kurang jelas apa dogsitu, tapi saya akan memperlakukannya sebagai setara, seperti kebanyakan webservers menerima akses ke direktori tanpa jejak /.
CodesInChaos

Jawaban:

50

Tak satu pun dari ini adalah otoritatif (karena REST tidak memiliki makna yang tepat). Tetapi dari makalah asli pada REST, URL lengkap (tidak berakhir pada /) menamai sumber daya, sedangkan yang berakhiran garis miring '/' adalah grup sumber daya (mungkin tidak dituliskan seperti itu).

GET dari URL dengan garis miring di bagian akhir seharusnya mencantumkan sumber daya yang tersedia.

GET http://example.com/dogs/          /* List all the dogs resources */

PUT pada URL dengan garis miring seharusnya menggantikan semua sumber daya.

PUT http://example.com/dogs/          /* Replace all the dogs resources */

HAPUS pada URL dengan garis miring seharusnya menghapus semua sumber

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

POST pada URL dengan garis miring seharusnya membuat sumber daya baru kemudian dapat diakses. Agar sesuai, sumber daya baru harus ada di direktori ini (meskipun banyak arsitektur ISTIRAH curang di sini).

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

dll.

Halaman wiki pada subjek tampaknya menjelaskannya dengan baik:

Lihat contoh https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services .

Martin York
sumber
Ini juga cocok dengan model path / url normal, di mana direktori sering ditulis dengan trailing/
CodesInChaos
4
Jadi apa yang harus terjadi jika Anda mengakses grup sumber daya tanpa jejak /?
Oberlies
1
@oberlies: Tergantung pada konteksnya. Tidak ada aturan keras dan cepat hanya praktik terbaik. Selalu ada expcetions ke aturan dan itu harus berarti apa yang Anda harapkan. Dalam contoh di atas: GET http://example.com/dogsdapat mengembalikan informasi meta tentang anjing (bukan daftar itu sendiri tetapi informasi meta tentang daftar anjing). Mungkin atau mungkin ini sebuah kesalahan.
Martin York
1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.Ini bukan satu-satunya tempat yang menyarankan untuk tidak menggunakan slash pelatihan
Laiv
@ Longv Saya tidak setuju dengan sentimen. Tapi tolong tautkan referensi yang lebih otoritatif (itu tautan lemah).
Martin York
17
Does anyone know the definitive answer?

Tidak ada satu karena tidak ada dokumen resmi tentang apa yang diperlukan untuk layanan yang dianggap tenang.

Yang mengatakan saya akan membiarkan garis miring hanya untuk kemudahan penggunaan. Sementara secara teknis ini dapat dilihat sebagai upaya untuk mengakses anjing dengan ID nol; Saya tidak melihat pengguna melakukan lompatan ini kecuali mereka telah membacanya di dokumentasi Anda. Saya dapat melihat pengguna yang mencoba menulis kode terhadap API Anda dan memasukkan garis miring hanya dari kebiasaan dan bertanya-tanya mengapa mereka mendapat respons 404 ketika mereka menginginkan daftar anjing.

Mike
sumber
Bagaimana dengan DELETE example.com/dogs ?
Benjamin Gruenbaum
karena anjing adalah induk dari semua anjing, menghapus anjing akan menghapus semua anjing dan dirinya sendiri. Jika Anda tidak melakukan itu, hypermedia Anda akan rusak
Gaz_Edge
@Gaz_Edge: In REST example.com/dogsadalah sumber daya yang sepenuhnya independen dari sumber daya apa pun example.com/dogs/X. Jadi DELETE pada example.com/dogstidak harus menghapus semua anjing / * (meskipun bisa jika itu adalah semantik). Tetapi DELETE example.com/dogs/harus menghapus semua anjing / *.
Martin York
3
Saya akan mengatakan sekali lagi bahwa karena tidak ada seperangkat aturan yang pasti tentang apa yang TETAP apa yang terjadi ketika Anda HAPUS / anjing atau / anjing / akan didasarkan pada apa yang Anda harapkan dari pelanggan API Anda harapkan. Apakah mungkin mereka benar-benar ingin menghapus semua anjing dengan satu permintaan? Jika demikian maka implementasikan seperti itu, jika tidak maka berikan respons 405 Metode Tidak Diizinkan.
Mike
1
Saya tahu ini adalah utas lama, tetapi saya sendiri baru-baru ini bertanya-tanya tentang ini. Untuk apa itu layak, OS X Bash shell memperlakukan foo, foo/dan foo////identik. Pada dasarnya sepertinya menghapus segmen jalur kosong. Jadi, jika Anda mengikuti pendekatan yang sama dengan layanan REST Anda, dogsdan dogs/akan merujuk pada hal yang sama.
Greg Brown
2

Dua arah.

Metode 1

Selalu gunakan garis miring untuk sumber daya apa pun yang mungkin mengandung anak-anak.

Coba pertimbangkan "DAPATKAN" pada direktori public_html dengan file.

Tidak mungkin ketika hello.html adalah file:

/hello.html
/hello.html/youagain.html

Tetapi mungkin ketika hello.html adalah direktori:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

Jadi, jika "hello.html" dapat memiliki anak maka selalu dan selamanya "/hello.html/" dan "/hello.html/index.html" (atau cukup /hello.html/) adalah daftar anak-anak ini .

Metode 2

Jadilah cerdas".

$ find
.
./hello.html
./hello.html/index.html

Perintah find tidak peduli dengan jenis hello.html. Direktori atau file, siapa peduli, itu adalah nama objek. Saat kami menulis "cp youagain.html hello.html", cp dapat mengetahui cara menangani hello.html. cp pintar. Server web Anda juga cerdas. Ini memiliki perpustakaan penanganan jalur. Ini memiliki routing. Itu dapat membuat stat dan memberi tahu Anda jika sebuah nama adalah objek atau direktori. Itu dapat mengarahkan bla ke bla / atau bahkan hanya menyajikan tanggapan yang sama untuk keduanya. Ini luar biasa !!! cara. Begitu banyak teknologi. Siapa yang mau hanya menyatukan string path ketika kita bisa melakukan semua itu ???

Samuel Danielson
sumber