Saya baru mengenal REST dan saya telah mengamati bahwa di beberapa layanan RESTful mereka menggunakan sumber daya URI yang berbeda untuk memperbarui / mendapatkan / menghapus dan membuat. Seperti
- Membuat - menggunakan / sumber daya dengan metode POST (mengamati jamak) di beberapa tempat menggunakan / sumber daya (tunggal)
- Perbarui - using / resource / 123 dengan metode PUT
- Dapatkan - Menggunakan / resource / 123 dengan metode GET
Saya sedikit bingung tentang konvensi penamaan URI ini. Apa yang harus kita gunakan jamak atau tunggal untuk penciptaan sumber daya? Apa yang harus menjadi kriteria saat memutuskan itu?
rest
resources
naming-conventions
uri
JPReddy
sumber
sumber
Jawaban:
Premis penggunaannya
/resources
adalah bahwa ia mewakili sumber daya "semua". Jika Anda melakukanGET /resources
, Anda kemungkinan akan mengembalikan seluruh koleksi. Dengan POSTing ke/resources
, Anda menambahkan ke koleksi.Namun, sumber daya individu tersedia di / sumber daya. Jika Anda melakukan
GET /resource
, Anda kemungkinan akan melakukan kesalahan, karena permintaan ini tidak masuk akal, sedangkan/resource/123
masuk akal.Menggunakan
/resource
bukan/resources
mirip dengan bagaimana Anda akan melakukan ini jika Anda bekerja dengan, katakanlah, sistem file dan kumpulan file dan/resource
merupakan "direktori" dengan individu123
,456
file di dalamnya.Tidak ada cara yang benar atau salah, pilih yang paling Anda sukai.
sumber
Bagi saya lebih baik memiliki skema yang Anda dapat memetakan langsung ke kode (mudah diotomatisasi), terutama karena kode adalah apa yang akan terjadi di kedua ujungnya.
sumber
Saya tidak melihat gunanya melakukan ini dan saya pikir itu bukan desain URI terbaik. Sebagai pengguna layanan RESTful saya berharap sumber daya daftar memiliki nama yang sama tidak peduli apakah saya mengakses daftar atau sumber daya tertentu 'dalam' daftar. Anda harus menggunakan pengidentifikasi yang sama tidak peduli apakah Anda ingin menggunakan sumber daya daftar atau sumber daya tertentu.
sumber
Jamak
orders/
mendapatkan daftar indeks pesanan.Sebagai contoh:
GET /resources
- mengembalikan daftar item sumber dayaPOST /resources
- Membuat satu atau banyak item sumber dayaPUT /resources
- memperbarui satu atau banyak item sumber dayaPATCH /resources
- Pembaruan sebagian atau beberapa item sumber dayaDELETE /resources
- menghapus semua item sumber dayaDan untuk item sumber daya tunggal:
GET /resources/:id
- Mengembalikan item sumber daya tertentu berdasarkan:id
parameterPOST /resources/:id
- membuat satu item sumber daya dengan id yang ditentukan (memerlukan validasi)PUT /resources/:id
- memperbarui item sumber daya tertentuPATCH /resources/:id
- memperbarui sebagian item sumber daya tertentuDELETE /resources/:id
- menghapus item sumber daya tertentuKepada para penganjur tunggal, pikirkan seperti ini: Apakah Anda akan meminta seseorang untuk
order
dan mengharapkan satu hal, atau daftar hal-hal? Jadi mengapa Anda mengharapkan layanan mengembalikan daftar barang saat Anda mengetik/order
?sumber
Order
adalah nama yang bagus untuk kelas yang berhubungan dengan instance objek tunggal yang merujuk pada satu urutan.OrderList
adalah nama untuk kelas yang berhubungan dengan banyakOrder
instance.Orders Table
adalah nama yang bagus untuk tabel database dari banyak pesanan.Tunggal
Convenience Things dapat memiliki nama jamak yang tidak teratur. Terkadang mereka tidak memilikinya. Tapi nama singular selalu ada.
mis. Alamat Pelanggan dari Alamat Pelanggan
Pertimbangkan sumber terkait ini.
Ini
/order/12/orderdetail/12
lebih mudah dibaca dan logis daripada/orders/12/orderdetails/4
.Tabel Database
Sumber daya mewakili entitas seperti tabel database. Itu harus memiliki nama tunggal yang logis. Inilah jawaban atas nama tabel.
Pemetaan kelas
Kelas selalu tunggal. Alat ORM menghasilkan tabel dengan nama yang sama dengan nama kelas. Karena semakin banyak alat yang digunakan, nama tunggal menjadi standar.
Baca lebih lanjut tentang Dilema Pengembang Dilema API
sumber
/clothe/12/trouser/34
:)clothe
adalah kata kerja. API Istirahat umumnya berpegang pada kata benda ketika berbicara tentang sumber daya dan menggunakan kata kerja saat menjelaskan tindakan. Bentuk tunggal adalahclout
, tetapi kuno dan kemungkinan akan lebih sesuai digantikan olehgarment
.Sedangkan praktik yang paling umum adalah APA TENANG di mana bentuk jamak digunakan misalnya
/api/resources/123
, ada satu kasus khusus di mana saya menemukan penggunaan nama tunggal lebih tepat / ekspresif daripada nama jamak. Ini adalah kasus hubungan satu-ke-satu. Khususnya jika item target adalah objek nilai (dalam paradigma desain-driven-domain).Mari kita asumsikan setiap sumber daya memiliki satu-ke-satu
accessLog
yang dapat dimodelkan sebagai objek nilai yaitu bukan entitas sehingga tidak ada ID. Itu bisa dinyatakan sebagai/api/resources/123/accessLog
. Kata kerja yang biasa (POST, PUT, DELETE, GET) akan secara tepat mengungkapkan maksud dan juga fakta bahwa hubungan tersebut memang satu-ke-satu.sumber
GET /users/123/location
harus mengambil lokasi tempat pengguna itu bekerja. BukanGET /users/123/locations
benar-benar menyesatkan sebagai konsumen?accessLog
dimodelkan sebagai atribut, atau nilai, dan bukan entitas, entitas harus tunggal. Jika Anda diberikan kepada rekayasa berlebihan, maka entri log akan menjadi entitas dan Anda akan memilikinya/api/accessLogEntries?resource=123
.Mengapa tidak mengikuti tren umum nama tabel database, di mana bentuk tunggal diterima secara umum? Pernah ke sana, melakukan itu - mari kita gunakan kembali.
Dilema Penamaan Tabel: Nama Singular vs. Plural
sumber
Saya terkejut melihat bahwa begitu banyak orang akan melompat pada kereta musik nomina jamak. Saat menerapkan konversi tunggal ke jamak, apakah Anda menangani kata benda jamak tidak teratur? Apakah Anda menikmati rasa sakit?
Lihat http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm
Ada banyak jenis jamak tidak beraturan, tetapi ini adalah yang paling umum:
Jenis kata benda Membentuk contoh jamak
sumber
Dari perspektif konsumen API, titik akhir harus dapat diprediksi demikian
Idealnya ...
GET /resources
harus mengembalikan daftar sumber daya.GET /resource
harus mengembalikan kode status 400 level.GET /resources/id/{resourceId}
harus mengembalikan koleksi dengan satu sumber daya.GET /resource/id/{resourceId}
harus mengembalikan objek sumber daya.POST /resources
Haruskah batch menciptakan sumber daya.POST /resource
harus membuat sumber daya.PUT /resource
harus memperbarui objek sumber daya.PATCH /resource
harus memperbarui sumber daya dengan memposting hanya atribut yang diubah.PATCH /resources
harus memperbarui sumber daya batch memposting hanya atribut yang diubah.DELETE /resources
harus menghapus semua sumber; hanya bercanda: 400 kode statusDELETE /resource/id/{resourceId}
Pendekatan ini adalah yang paling fleksibel dan kaya fitur, tetapi juga yang paling memakan waktu untuk dikembangkan. Jadi, jika Anda terburu-buru (yang selalu terjadi dengan pengembangan perangkat lunak) cukup beri nama titik akhir
resource
atau bentuk jamakresources
. Saya lebih suka bentuk tunggal karena memberi Anda pilihan untuk introspeksi dan mengevaluasi secara programatis karena tidak semua bentuk jamak berakhir pada 's'.Setelah mengatakan semua itu, untuk alasan apa pun yang dipilih pengembang praktik yang paling umum adalah menggunakan bentuk jamak. Ini pada akhirnya adalah rute yang saya pilih dan jika Anda melihat apis populer seperti
github
dantwitter
, inilah yang mereka lakukan.Beberapa kriteria untuk memutuskan dapat:
Jadi terserah kamu. Apapun yang Anda lakukan, konsistenlah.
sumber
POST /users
seharusnya membuat pengguna tunggal, menambahkannya ke koleksi. Saya tidak setuju.POST /users
harus membuat daftar pengguna (bahkan jika itu adalah daftar 1), di mana sebagaimanaPOST /user
seharusnya membuat satu pengguna. Saya tidak melihat alasan mengapa titik akhir sumber daya jamak dan tunggal tidak dapat hidup berdampingan. Mereka menggambarkan perilaku yang berbeda, dan seharusnya tidak mengejutkan siapa pun dari fungsi mereka.POST users/<id>
akan membuat pengguna baru.PUT /users/<id>
daripadaPOST
.POST
memiliki interpretasi "tambahkan ini ke koleksi, dan tentukan id sebagai bagian dari itu".PUT
memiliki interpretasi "perbarui (atau tambahkan) sumber ini dengan id ini." Lihat restcookbook.com/HTTP%20Methods/put-vs-post untuk penjelasan lebih lanjut tentang prinsip ini.Dua sen saya: metode yang menghabiskan waktu mereka berubah dari jamak menjadi tunggal atau sebaliknya adalah pemborosan siklus CPU. Saya mungkin jadul, tetapi pada masa saya hal-hal seperti itu disebut sama. Bagaimana cara mencari metode mengenai orang? Ekspresi reguler tidak akan mencakup orang dan orang tanpa efek samping yang tidak diinginkan.
Bentuk jamak bahasa Inggris bisa sangat sewenang-wenang dan mereka membebani kode dengan sia-sia. Tetap pada satu konvensi penamaan. Bahasa komputer seharusnya tentang kejelasan matematika, bukan tentang meniru bahasa alami.
sumber
Saya lebih suka menggunakan bentuk tunggal untuk kesederhanaan dan konsistensi.
Misalnya, pertimbangkan url berikut:
/ pelanggan / 1
Saya akan memperlakukan pelanggan sebagai koleksi pelanggan, tetapi untuk kesederhanaan, bagian pengumpulan dihapus.
Contoh lain:
/ peralatan / 1
Dalam hal ini, peralatan bukan bentuk jamak yang benar. Jadi memperlakukannya sebagai koleksi peralatan dan menghapus koleksi untuk kesederhanaan membuatnya konsisten dengan kasus pelanggan.
sumber
POST /customer
seharusnya melakukan hal yang sama - masukkan satu pelanggan?POST /customer
membaca untuk saya seolah-olah POST kepadathe
pelanggan. Bukan koleksi Pelanggan. Namun, saya akui bahwa jamak atau bukan jamak adalah preferensi. Selama mereka tidak tercampur seperti Jawaban lainnya. Itu akan sangat membingungkan.Id dalam rute harus dilihat sama dengan indeks pada daftar, dan penamaan harus dilanjutkan.
Tetapi beberapa sumber daya tidak menggunakan id di rute mereka karena hanya ada satu, atau pengguna tidak pernah memiliki akses ke lebih dari satu, jadi itu bukan daftar:
sumber
Dengan konvensi penamaan, biasanya aman untuk mengatakan "pilih saja dan patuhi", yang masuk akal.
Namun, setelah harus menjelaskan REST kepada banyak orang, mewakili titik akhir sebagai jalur pada sistem file adalah cara paling ekspresif untuk melakukannya.
Ini stateless (file ada atau tidak ada), hierarkis, sederhana, dan familier - Anda sudah tahu cara mengakses file statis, baik lokal maupun via http.
Dan dalam konteks itu, aturan linguistik hanya bisa membuat Anda sejauh yang berikut:
Dan saya suka itu.
Meskipun, di sisi lain - ini adalah direktori Anda, Anda dapat menamainya "a-resource-or-multiple-resources" jika itu yang Anda inginkan. Bukan itu yang terpenting.
Yang penting adalah bahwa jika Anda meletakkan file bernama "123" di bawah direktori bernama "resourceS" (menghasilkan
/resourceS/123
), Anda tidak dapat berharap itu dapat diakses melalui/resource/123
.Jangan mencoba menjadikannya lebih pintar dari yang seharusnya - mengubah dari jamak ke jamuan bergantung pada jumlah sumber daya yang saat ini Anda akses mungkin secara estetis menyenangkan bagi sebagian orang, tetapi itu tidak efektif dan tidak masuk akal dalam sistem hierarkis .
Catatan: Secara teknis, Anda dapat membuat "tautan simbolis", sehingga
/resources/123
dapat juga diakses melalui/resource/123
, tetapi yang pertama masih harus ada!sumber
Silahkan lihat pada Google 's API Design Guide: Nama Sumber Daya untuk take lain pada sumber daya penamaan.
Pendeknya:
Bacaan yang bermanfaat jika Anda memikirkan hal ini.
sumber
Menggunakan jamak untuk semua metode lebih praktis setidaknya dalam satu aspek: jika Anda mengembangkan dan menguji sumber daya API menggunakan Postman (atau alat serupa), Anda tidak perlu mengedit URI saat beralih dari GET ke PUT ke POST dll. .
sumber
Kedua representasi itu bermanfaat. Saya telah menggunakan singular untuk kenyamanan selama beberapa waktu, belok mungkin sulit. Pengalaman saya dalam mengembangkan REST API yang unik, para pengembang mengkonsumsi titik akhir tidak memiliki kepastian dalam bentuk apa hasilnya. Saya sekarang lebih suka menggunakan istilah yang paling menggambarkan bentuk respons.
Jika semua sumber daya Anda berada di tingkat atas, maka Anda bisa lolos dengan representasi tunggal. Menghindari infleksi adalah kemenangan besar.
Jika Anda melakukan semacam tautan mendalam untuk mewakili pertanyaan tentang hubungan, maka pengembang yang menulis menentang API Anda dapat dibantu dengan memiliki konvensi yang lebih ketat.
Konvensi saya adalah bahwa setiap tingkat kedalaman dalam URI menggambarkan interaksi dengan sumber daya induk, dan URI lengkap harus secara implisit menggambarkan apa yang diambil.
Misalkan kita memiliki model berikut.
Jika saya perlu menyediakan sumber daya yang memungkinkan klien mendapatkan pengelola teman tertentu dari pengguna tertentu, itu mungkin terlihat seperti:
GET /users/{id}/friends/{friendId}/manager
Berikut ini adalah beberapa contoh lainnya:
GET /users
- daftar sumber daya pengguna dalam koleksi pengguna globalPOST /users
- membuat pengguna baru dalam koleksi pengguna globalGET /users/{id}
- mengambil pengguna tertentu dari koleksi pengguna globalGET /users/{id}/manager
- dapatkan pengelola pengguna tertentuGET /users/{id}/friends
- dapatkan daftar teman penggunaGET /users/{id}/friends/{friendId}
- dapatkan teman pengguna tertentuLINK /users/{id}/friends
- tambahkan asosiasi teman ke pengguna iniUNLINK /users/{id}/friends
- hapus asosiasi teman dari pengguna iniPerhatikan bagaimana setiap level memetakan ke orangtua yang dapat ditindaklanjuti. Menggunakan orang tua yang berbeda untuk objek yang sama adalah berlawanan dengan intuisi. Mengambil sumber daya di
GET /resource/123
tidak meninggalkan indikasi bahwa menciptakan sumber daya baru harus dilakukan diPOST /resources
sumber
Saya tahu kebanyakan orang antara memutuskan untuk menggunakan jamak atau tunggal. Masalah yang belum diatasi di sini adalah bahwa klien perlu tahu mana yang Anda gunakan, dan mereka selalu cenderung membuat kesalahan. Dari sinilah saran saya berasal.
Bagaimana dengan keduanya? Dan maksud saya, gunakan singular untuk seluruh API Anda dan kemudian buat rute untuk meneruskan permintaan yang dibuat dalam bentuk jamak ke bentuk tunggal. Sebagai contoh:
Anda mendapatkan fotonya. Tidak ada yang salah, usaha minimal, dan klien akan selalu melakukannya dengan benar.
sumber
/resources
dan selalu diarahkan/resource
, Anda telah melakukannya dengan salah. Jika orang lain menggunakan API Anda, mereka dapat menggunakan URL yang benar secara langsung atau dialihkan (yang berfungsi tetapi salah) dan Andalah yang membuka jalan yang salah.Saya tidak suka melihat
{id}
bagian dari URL tumpang tindih dengan sub-sumber daya, karena secaraid
teoritis bisa menjadi apa saja dan akan ada ambiguitas. Ini menggabungkan konsep yang berbeda (pengidentifikasi dan nama sub-sumber daya).Masalah serupa sering terlihat dalam
enum
konstanta atau struktur folder, di mana konsep berbeda dicampur (misalnya, ketika Anda memiliki folderTigers
,Lions
danCheetahs
, dan kemudian juga folder yang disebutAnimals
pada tingkat yang sama - ini tidak masuk akal karena satu adalah subset dari lain).Secara umum saya pikir bagian nama terakhir dari titik akhir harus tunggal jika berurusan dengan entitas tunggal pada suatu waktu, dan jamak jika berurusan dengan daftar entitas.
Jadi titik akhir yang berhubungan dengan satu pengguna:
Lalu ada sumber daya terpisah untuk melakukan kueri pada pengguna, yang umumnya mengembalikan daftar:
Dan di sini beberapa contoh sub-sumber daya yang berhubungan dengan pengguna tertentu:
Buat teman (banyak ke banyak tautan):
Tidak pernah ada ambiguitas, dan penamaan jamak atau tunggal sumber daya adalah petunjuk kepada pengguna apa yang dapat mereka harapkan (daftar atau objek). Tidak ada batasan pada
id
s, secara teoritis memungkinkan untuk memiliki pengguna dengan idnew
tanpa tumpang tindih dengan nama sub-sumber daya (potensial masa depan).sumber
Gunakan Singular dan manfaatkan konvensi bahasa Inggris yang terlihat dalam misalnya "Direktori Bisnis".
Banyak hal yang dibaca dengan cara ini: "Book Case", "Dog Pack", "Art Gallery", "Festival Film", "Car Lot", dll.
Ini cocok dengan jalur url dari kiri ke kanan. Jenis barang di sebelah kiri. Setel jenis di sebelah kanan.
Apakah
GET /users
benar-benar pernah mengambil sekelompok pengguna? Tidak biasanya. Itu mengambil satu set bertopik berisi kunci dan mungkin nama pengguna. Jadi sebenarnya tidak benar/users
. Ini adalah indeks pengguna, atau "indeks pengguna" jika Anda mau. Kenapa tidak menyebutnya begitu? Itu adalah/user/index
. Karena kami telah menamai tipe yang ditetapkan, kami dapat memiliki beberapa tipe yang menunjukkan proyeksi pengguna yang berbeda tanpa menggunakan parameter kueri misalnyauser/phone-list
atau/user/mailing-list
.Dan bagaimana dengan Pengguna 300? Itu masih
/user/300
.Sebagai penutup, HTTP hanya dapat memiliki satu respons terhadap satu permintaan. Jalan selalu merujuk pada sesuatu yang tunggal.
sumber
Bagi saya bentuk jamak memanipulasi koleksi , sedangkan singulars memanipulasi item di dalam koleksi itu.
Pengumpulan memungkinkan metode DAPATKAN / POST / HAPUS
Item memungkinkan metode DAPATKAN / PUT / HAPUS
Sebagai contoh
POST pada / siswa akan menambah siswa baru di sekolah.
DELETE pada / siswa akan menghapus semua siswa di sekolah.
DELETE pada / siswa / 123 akan mengeluarkan siswa 123 dari sekolah.
Mungkin terasa tidak penting tetapi beberapa insinyur terkadang lupa id. Jika rute selalu jamak dan melakukan DELETE, Anda mungkin secara tidak sengaja menghapus data Anda. Sedangkan kehilangan id pada singular akan mengembalikan 404 rute yang tidak ditemukan.
Untuk lebih memperluas contoh jika API seharusnya mengekspos beberapa sekolah, maka sesuatu seperti
DELETE pada / sekolah / abc / siswa akan menghapus semua siswa di sekolah
abc
.Memilih kata yang tepat terkadang merupakan tantangan tersendiri, tetapi saya suka mempertahankan pluralitas untuk koleksi. Misal
cart_items
ataucart/items
terasa benar. Sebaliknya menghapuscart
, menghapus objek gerobak itu sendiri dan bukan item dalam gerobak;).sumber
Bagaimana tentang:
/resource/
(tidak/resource
)/resource/
berarti folder berisi sesuatu yang disebut "sumber daya", itu adalah folder "sumber daya".Dan juga saya pikir konvensi penamaan tabel database adalah sama, misalnya, tabel yang disebut 'pengguna' adalah "tabel pengguna", ini berisi sesuatu yang disebut "pengguna".
sumber
Saya lebih suka menggunakan jamak (
/resources
) dan tunggal (/resource/{id}
) karena saya pikir itu lebih jelas memisahkan logika antara bekerja pada pengumpulan sumber daya dan bekerja pada sumber daya tunggal.Sebagai efek samping penting dari ini, ini juga dapat membantu mencegah seseorang menggunakan API secara salah. Misalnya, perhatikan kasus di mana pengguna salah mencoba untuk mendapatkan sumber daya dengan menetapkan Id sebagai parameter seperti ini:
Dalam hal ini, di mana kami menggunakan versi jamak, server kemungkinan besar akan mengabaikan parameter Id dan mengembalikan daftar semua sumber daya. Jika pengguna tidak hati-hati, ia akan berpikir bahwa panggilan itu berhasil dan menggunakan sumber daya pertama dalam daftar.
Di sisi lain, saat menggunakan bentuk tunggal:
server kemungkinan besar akan mengembalikan kesalahan karena ID tidak ditentukan dengan cara yang benar, dan pengguna harus menyadari bahwa ada sesuatu yang salah.
sumber