REST URI convention - Nama sumber daya tunggal atau jamak saat membuatnya

529

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?

JPReddy
sumber
9
Mengikuti topik ini, saya telah mengumpulkan beberapa contoh API REST yang terkenal di sebuah artikel: inmensosofa.blogspot.com/2011/10/… .
jjmontes
3
Kesimpulan yang saya capai setelah membaca semua jawaban di bawah ini: Selalu gunakan singular karena (a) konsisten, (b) memetakan langsung ke kelas singular dan nama tabel, (c) beberapa nomina jamak tidak beraturan (tidak dapat diprediksi) dalam bahasa Inggris
Will Sheppard
Lihat jawaban ini untuk tautan ke konvensi penamaan tabel tunggal, dan ada artikel lain yang menyebutkan masalah persis ini . Dilema Pengembang API Rest - terima kasih @Sorter
Will Sheppard

Jawaban:

281

Premis penggunaannya /resourcesadalah bahwa ia mewakili sumber daya "semua". Jika Anda melakukan GET /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/123masuk akal.

Menggunakan /resourcebukan /resourcesmirip dengan bagaimana Anda akan melakukan ini jika Anda bekerja dengan, katakanlah, sistem file dan kumpulan file dan /resourcemerupakan "direktori" dengan individu 123, 456file di dalamnya.

Tidak ada cara yang benar atau salah, pilih yang paling Anda sukai.

Will Hartung
sumber
55
Jawaban bagus! Tetapi direktori "default" di Windows memiliki nama jamak . Seperti "Program Files", "Users", "Documents", "Videos" dll. Saya juga lebih sering menjumpai nama jamak di url situs web.
Dmitry Gonchar
50
konvensi defacto cukup banyak orang dan API di luar sana adalah menjaganya agar selalu jamak. Id tentukan SATU mobil sumber daya / id
PositiveGuy
205
"Tidak ada cara yang benar atau salah, pergi dengan apa yang Anda sukai." Ah kalimat terkenal yang sering saya dengar dan menjadi sakit dan lelah mendengar orang. Konvensi penting dan HARUS diperdebatkan secara konstruktif di antara masyarakat, di situlah solusi yang lebih baik muncul dan praktik yang baik. Ketika Anda menggunakan bentuk jamak dan tunggal untuk nama sumber daya di URI, itu menyulitkan kode dan API Anda karena pengguna dan kode di belakang API harus menjelaskan hal itu dalam rute dan logika untuk membedakan tunggal vs jamak sedangkan jika Anda hanya tetap dengan jamak sepanjang waktu Anda tidak memiliki masalah.
PositiveGuy
30
@TomaszPluskiewicz Anda sepenuhnya benar bahwa klien tidak peduli. Sebagai pengembang perangkat lunak kita harus peduli - dan untuk itu saya setuju dengan komentar WTF bahwa debat konstruktif tentang konvensi itu berharga.
Travis D
12
Jadi bisakah seseorang memberikan jawaban satu kata dan menerimanya sehingga saya tidak perlu membaca ini semua (lagi).
Ben George
624

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.

GET  /orders          <---> orders 
POST /orders          <---> orders.push(data)
GET  /orders/1        <---> orders[1]
PUT  /orders/1        <---> orders[1] = data
GET  /orders/1/lines  <---> orders[1].lines
POST /orders/1/lines  <---> orders[1].lines.push(data) 
jla
sumber
22
Kesulitan atau kemudahan ini adalah karena tidak menghormati HATEOS. Seharusnya tidak masalah apakah itu jamak atau tunggal atau apa pun. Anda harus menghormati uri yang dikirim dari server dan tidak "membangun" uri Anda di klien. Maka Anda memiliki 0 pemetaan yang harus dilakukan untuk kode Anda.
richard
7
@richard Klien masih harus melakukan pemetaan. Dalam HATEOS mereka harus memetakan ke nama yang mewakili hubungan (rel) dengan konstruksi URI. Rel, metode (kata kerja) dan Content-Type kemudian membentuk media sumber daya. Ini tidak menghalangi kebutuhan untuk desain URI yang baik. Meskipun klien mungkin mendahulukan nama rel, para pengembang API masih membutuhkan standar yang dapat dibaca manusia untuk konstruksi URI.
4
Ini jawaban yang lebih baik menurut saya. Kecuali bahwa saya selalu lebih suka menggunakan Singular daripada jamak. User.getList (), User.getById, User.delete dll.
Eastern Monk
3
Saya suka kesederhanaannya. Pemetaan ini juga memiliki manfaat membuat dokumentasi dan tes pada rute yang sangat mudah untuk ditulis.
delos
5
Ini masuk akal bagi saya. Namun, kami adalah toko basis data pertama, artinya kami menghasilkan entitas kode dan api dari skema basis data kami. Dan standar database cenderung menganjurkan nama tabel tunggal, jadi kita akan pergi dengan itu, tetapi masih di bawah logika yang sama dengan jawaban ini.
André C. Andersen
274

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.

Jan Deinhard
sumber
69
Ini adalah jawaban terbaik sejauh yang saya ketahui. Saya menghargai bahwa para perancang API menyukai kebenaran linguistik dengan mengatakan "dapatkan sumber daya # 123", tetapi ini merupakan kerumitan pengkodean tambahan saat menulis klien API serta dokumentasi bantuan. (GET / api / orang vs. GET / api / orang / 123? Euuuchh.) .... alih-alih memikirkannya seperti "dapatkan sumber daya # 123", frasa di kepala Anda seperti "dapatkan dari kumpulan sumber daya yang cocok dengan # 123 ".
Warren Rumak
5
Membedakan sumber daya jamak / tunggal bukan tentang kebenaran linguistik tetapi tentang skala. / karyawan / 12 membacakan kepada saya sebagai bagian dari sumber daya karyawan dengan id '12' (itu bisa berarti apa saja, misalnya permintaan pencarian yang disimpan pada karyawan yang baru dipecat). Jika Anda membaca di atas sebagai karyawan dengan id '12', bagaimana Anda akan mewakili subset? Satu-satunya pilihan adalah dengan membuat koleksi pembeda bijih URI yang lebih kompleks yang berisi objek dari objek itu sendiri (yaitu tunggal vs jamak).
Erik
9
Memilih / karyawan / 12 untuk mewakili permintaan pencarian pada karyawan yang baru saja dipecat (atau setiap subset) akan menjadi desain yang buruk saya pikir. Jika Anda ingin mewakili himpunan bagian dalam bentuk apa pun dari saya sarankan untuk memperkenalkan mereka sebagai sumber daya (dengan nama yang tepat) dengan hak mereka sendiri.
Jan Deinhard
3
Ini tidak ada hubungannya dengan pemahaman untuk klien. Ini tentang mengatasi berbagai hal dengan URL yang berbeda. Dan mampu merespons semua metode HTTP tanpa mengalami konflik. Anda dapat memiliki sumber daya yang merupakan kumpulan item, dan sumber daya yang mewakili item itu sendiri. Untuk semua yang saya pedulikan, sumber daya koleksi dapat example.org/166316e2-e1 dan satu item tertentu dalam koleksi tersebut example.org/20d68348-ccc-001c4200de . Klien tidak boleh membuat URL (yang jelas-jelas tidak menskala, itu bukan RESTful dan untuk itulah jenis hubungan tautan).
Erik
4
Jika menurut Anda URL sewenang-wenang itu tidak cantik, jangan ragu untuk mengidentifikasi sumber daya koleksi dengan nama jamak dan item individual dengan nama tunggal. Jika Anda tidak menyukai URL bahasa Inggris dan bahasa alami Anda tidak mendukung cara notasi singualr / jamak menggunakan hal lain untuk mendefinisikannya dalam bahasa pilihan Anda, saya kira semua bahasa memungkinkan Anda untuk membedakan '/ the-collection-of- bla / 2321 'versus' bla / 61 'secara tertulis. Dan masing-masing dari dua sumber daya yang berbeda tersebut mewakili hasil yang sama sekali berbeda saat mengirim GET / PUT / DELETE / POST / PATCH dan lainnya.
Erik
77

Jamak

  • Sederhana - semua url mulai dengan awalan yang sama
  • Logis - orders/mendapatkan daftar indeks pesanan.
  • Standar - Standar yang paling banyak diadopsi diikuti oleh sebagian besar API publik dan swasta.

Sebagai contoh:

GET /resources - mengembalikan daftar item sumber daya

POST /resources - Membuat satu atau banyak item sumber daya

PUT /resources - memperbarui satu atau banyak item sumber daya

PATCH /resources - Pembaruan sebagian atau beberapa item sumber daya

DELETE /resources - menghapus semua item sumber daya

Dan untuk item sumber daya tunggal:

GET /resources/:id- Mengembalikan item sumber daya tertentu berdasarkan :idparameter

POST /resources/:id - membuat satu item sumber daya dengan id yang ditentukan (memerlukan validasi)

PUT /resources/:id - memperbarui item sumber daya tertentu

PATCH /resources/:id - memperbarui sebagian item sumber daya tertentu

DELETE /resources/:id - menghapus item sumber daya tertentu

Kepada para penganjur tunggal, pikirkan seperti ini: Apakah Anda akan meminta seseorang untuk orderdan mengharapkan satu hal, atau daftar hal-hal? Jadi mengapa Anda mengharapkan layanan mengembalikan daftar barang saat Anda mengetik /order?

Eric Knudtson
sumber
10
Singular : Dalam hal ini, ketika bagian dari sistem Anda hanya satu objek (0-1, ada atau tidak) misalnya pengguna / 1 / avatar Anda dapat menggunakan bentuk singular untuk memberi label objek tunggal ini (mis. Avatar) - contoh lebih rinci di sini: stackoverflow .com / a / 38296217/860099 . BTW - jawaban yang sangat bagus :)
Kamil Kiełczewski
Bagaimana dengan pemetaan ke nama kelas dan tabel, yang harus tunggal? (lihat jawaban lain )
Will Sheppard
@ WillSheppard - Nama kelas terbaik dalam bentuk tunggal dan nama tabel terbaik dalam bentuk jamak. Sebagai contoh Orderadalah nama yang bagus untuk kelas yang berhubungan dengan instance objek tunggal yang merujuk pada satu urutan. OrderListadalah nama untuk kelas yang berhubungan dengan banyak Orderinstance. Orders Tableadalah nama yang bagus untuk tabel database dari banyak pesanan.
Eric Knudtson
Saya ingin MENDAPATKAN / memesan tetapi saya hanya ingin / 1
jim smith
@ jim-smith lalu mengapa Anda tidak meminta / 1 dari kumpulan pengguna dengan GET / pengguna / 1?
Rohmer
49

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/12lebih 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

Tukang sortir
sumber
39
Nama tunggal selalu ada /clothe/12/trouser/34 :)
Gert Arnold
18
@GertArnold, kata itu clotheadalah kata kerja. API Istirahat umumnya berpegang pada kata benda ketika berbicara tentang sumber daya dan menggunakan kata kerja saat menjelaskan tindakan. Bentuk tunggal adalah clout, tetapi kuno dan kemungkinan akan lebih sesuai digantikan oleh garment.
Steve Buzonas
@SteveBuzonas Dan untuk celana panjang dan kacamata hitam?
Koray Tugay
32

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 accessLogyang 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.

redzedi
sumber
4
Usaha yang bagus. Tetapi akan lebih baik sebagai "accessLogEntries". :-)
Tom Russell
8
@ TomRussell kenapa? Implikasi dari ini penting. Saya mengerti mengapa Anda akan menggunakan jamak bahkan ketika Anda mengakses sumber daya oleh pengidentifikasi, tetapi untuk banyak-ke-satu atau satu-ke-satu itu cukup menyesatkan. Pertimbangkan api yang mengelola anggota staf untuk perusahaan multi-lokasi. Setiap anggota staf bekerja di satu lokasi. GET /users/123/locationharus mengambil lokasi tempat pengguna itu bekerja. BukanGET /users/123/locations benar-benar menyesatkan sebagai konsumen?
Carrie Kendall
1
@CrierieKendall Saya mengerti maksud Anda. Karena accessLogdimodelkan 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.
Tom Russell
Setuju, meskipun, saya pikir itu melanggar konvensi pluralize semua hal. Itu yang rumit. Bagi saya, ini penting daripada sebuah API yang lurus: dokumentasi harus memuji implementasi yang sudah lurus.
Carrie Kendall
Saya lebih dari seorang programmer daripada orang sistem atau database jadi saya suka API yang menceritakan sebuah cerita daripada mematuhi konvensi. Implikasinya untuk dokumentasi otomatis adalah nyata.
Tom Russell
26

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

Slawomir
sumber
8
Das Auto jauh lebih baik daripada Die Autos. Juga, konvensi bahasa Inggris jamak tidak konsisten.
FlavourScape
7
Namespace sumber daya adalah masalah semantik, bukan implementasi. Jadi, menggunakan analogi tabel DB, tidak terlalu beruntung. Juga ketika bekerja dengan DB-s Anda hanya memanipulasi tabel, meskipun tentu saja Anda dapat mempengaruhi konten (baris), tetapi dalam REST tidak ada kendala untuk memanipulasi satu sumber daya secara langsung.
arpadf
3
Saya pikir ini analogi yang baik, tetapi lebih penting daripada memutuskan apakah akan tunggal atau jamak adalah konsisten dengan mana pun yang Anda pilih. Anda tidak akan menyisipkan ke Pengguna dan kemudian pilih dari Pengguna. Aturan yang sama harus berlaku untuk sumber daya REST - jangan ganti namanya tergantung apa yang Anda lakukan.
Todd Menier
3
Bukan hanya nama tabel, tetapi juga sebanding dengan nama kelas di OO (kelas saya akan disebut Pelanggan, bukan Pelanggan).
bytedev
Dalam hal ini, semantik terlalu penting untuk sekadar menerima tren yang "sudah didefinisikan"
Cattani Simone
19

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

Ends with -fe   Change f to v then Add -s   
    knife   knives 
    life   lives 
    wife   wives
Ends with -f    Change f to v then Add -es  
    half   halves 
    wolf   wolves
    loaf   loaves
Ends with -o    Add -es 
    potato   potatoes
    tomato   tomatoes
    volcano   volcanoes
Ends with -us   Change -us to -i    
    cactus   cacti
    nucleus   nuclei
    focus   foci
Ends with -is   Change -is to -es   
    analysis   analyses
    crisis   crises
    thesis   theses
Ends with -on   Change -on to -a    
    phenomenon   phenomena
    criterion   criteria
ALL KINDS   Change the vowel or Change the word or Add a different ending   
     man   men
     foot   feet
     child   children
     person   people
     tooth   teeth
     mouse   mice
 Unchanging Singular and plural are the same    
     sheep deer fish (sometimes)
Stephan Erickson
sumber
5
Saya tidak mengerti keprihatinan di sini. Kita tidak seharusnya mengubah bentuk tunggal menjadi jamak secara terprogram. Sebagian besar bentuk jamak di atas terkenal, dan seharusnya tidak menjadi perhatian. Jika seseorang memiliki pengetahuan bahasa Inggris yang buruk, ia akan mengeja bagian mana pun dari variabel Anda secara tidak benar. Juga, sesuai dengan logika Anda, apakah Anda juga merekomendasikan menggunakan bentuk tunggal untuk merujuk koleksi dalam kode sumber juga?
kishor borate
1
Ada kata-kata bahasa Inggris yang tidak teratur ke titik di mana sering menjadi masalah bahkan di dalam Anglosphere dan istilah-istilah yang umum digunakan seperti indeks / indeks / indeks, vertix / vertix / verteks, matriks / matriks / matriks, radius / radius / jari-jari, dll. Saya tidak melihat gunanya membuat jalur REST jamak, karena jika mereka semua konsisten tunggal, itu hanya lebih jelas bagi semua orang.
damd
@kishorborate, Menggunakan jamak sebagai URI lebih rentan kesalahan, bahkan untuk penutur asli bahasa Inggris. Seperti yang ditunjukkan damd, bentuk jamak seperti indeks / indeks / indeks menimbulkan lebih banyak masalah. Dan ada kata benda yang tak terhitung. Mencampur nomina yang tak terhitung dengan bentuk jamak adalah masalah lain. Mengapa mempersulit programmer untuk menghabiskan lebih banyak waktu untuk ini? Saya sarankan menggunakan singulars untuk semuanya. Jika ada / {id}, maka API harus mengembalikan satu catatan. Jika tidak ada / {id} yang mengikuti, maka API harus mengembalikan koleksi.
Daming Fu
3
@DamingFu Sumber daya tunggal mungkin tidak selalu memiliki id yang terkait dengannya. misalnya. / user / {id} / nickName Dengan melihatnya, tidak jelas, apakah akan mengembalikan daftar nama panggilan atau nama panggilan tunggal? Karenanya, API lebih intuitif ketika menggunakan bentuk jamak. Ya, beberapa kata akan memiliki bentuk jamak yang tidak teratur. Bagi seseorang yang membaca bentuk jamak, bukan masalah. Masalahnya hanya saat menulis tanda tangan API. Tetapi frekuensi kata-kata seperti itu tidak tinggi, juga, menemukan bentuk jamak dari kata apa pun tidak memakan waktu. Ini pertukaran yang harus kita terima, untuk membuat API lebih intuitif.
kishor borate
15

Dari perspektif konsumen API, titik akhir harus dapat diprediksi demikian

Idealnya ...

  1. GET /resources harus mengembalikan daftar sumber daya.
  2. GET /resource harus mengembalikan kode status 400 level.
  3. GET /resources/id/{resourceId} harus mengembalikan koleksi dengan satu sumber daya.
  4. GET /resource/id/{resourceId} harus mengembalikan objek sumber daya.
  5. POST /resources Haruskah batch menciptakan sumber daya.
  6. POST /resource harus membuat sumber daya.
  7. PUT /resource harus memperbarui objek sumber daya.
  8. PATCH /resource harus memperbarui sumber daya dengan memposting hanya atribut yang diubah.
  9. PATCH /resources harus memperbarui sumber daya batch memposting hanya atribut yang diubah.
  10. DELETE /resourcesharus menghapus semua sumber; hanya bercanda: 400 kode status
  11. DELETE /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 resourceatau 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 githubdantwitter , inilah yang mereka lakukan.

Beberapa kriteria untuk memutuskan dapat:

  1. Apa kendala waktu saya?
  2. Operasi apa yang akan saya izinkan konsumen saya lakukan?
  3. Seperti apa bentuk permintaan dan hasil payload?
  4. Apakah saya ingin dapat menggunakan refleksi dan mengurai URI dalam kode saya?

Jadi terserah kamu. Apapun yang Anda lakukan, konsistenlah.

cosbor11
sumber
1
Sepertinya bentuk jamak telah dipilih karena pengembang tampaknya menganggap bahwa semua sumber daya secara inheren bagian dari beberapa koleksi. Namun, "konvensi yang diterima" tampaknya mengindikasikan yang POST /usersseharusnya membuat pengguna tunggal, menambahkannya ke koleksi. Saya tidak setuju. POST /usersharus membuat daftar pengguna (bahkan jika itu adalah daftar 1), di mana sebagaimana POST /userseharusnya 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.
naksir
Apakah tidak ada konvensi untuk menentukan id sumber daya di jalur? Jika demikian, tampaknya banyak diabaikan. Misalnya, POST users/<id>akan membuat pengguna baru.
Tom Russell
1
@ TomRussell biasanya server membuat id, jadi Anda belum tahu id to POST.
Alex
3
@ TomRussell, ketika klien menentukan (semacam) id saat membuat sumber daya baru, itu lebih umum untuk digunakan PUT /users/<id>daripada POST. POSTmemiliki interpretasi "tambahkan ini ke koleksi, dan tentukan id sebagai bagian dari itu". PUTmemiliki interpretasi "perbarui (atau tambahkan) sumber ini dengan id ini." Lihat restcookbook.com/HTTP%20Methods/put-vs-post untuk penjelasan lebih lanjut tentang prinsip ini.
Jochem Schulenklopper
Saya tidak percaya perbandingan dengan Twitters API adil karena mereka menggunakan bentuk jamak untuk semua titik akhir mereka. Mereka tidak mencampurkan Plural dan Singular untuk Elemen yang sama.
Andrew T Finnell
7

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.

Guichito
sumber
2
Kode alamat ini yang mencoba untuk "otomatis menghasilkan / memotong-motong" titik akhir (ada banyak perpustakaan berpendapatan yang menganggap pluralitas / singularitas dan upaya untuk memetakan); Namun, ini tidak berlaku untuk nama titik akhir yang dipilih secara eksplisit tidak lebih dari memilih kata yang tepat (terlepas dari bagaimana itu kata jamak).
user2864740
6

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.

ivxivx
sumber
2
POST / pelanggan terdengar seperti itu akan menggantikan satu-satunya pelanggan. Ini adalah kesedihan terbesar saya dengan menggunakan nama sumber tunggal.
Andrew T Finnell
2
@ andrew-t-finnell Bukankah POST /customerseharusnya melakukan hal yang sama - masukkan satu pelanggan?
donmutti
Ini memasukkan satu Pelanggan ke dalam koleksi Pelanggan. POST /customermembaca untuk saya seolah-olah POST kepada thepelanggan. Bukan koleksi Pelanggan. Namun, saya akui bahwa jamak atau bukan jamak adalah preferensi. Selama mereka tidak tercampur seperti Jawaban lainnya. Itu akan sangat membingungkan.
Andrew T Finnell
"POST kepada pelanggan" tidak masuk akal dalam kasus ini. POST tidak menggantikan, itu menyisipkan. Mungkin jika itu POST / pelanggan / 1 saya bisa melihat dilema, tetapi bahkan itu tidak masuk akal dari perspektif REST, karena apa yang Anda masukkan? Ini akan menjadi / pelanggan / 1 / faktur atau / pelanggan / 1 / tanda terima, dll
damd
5

Id dalam rute harus dilihat sama dengan indeks pada daftar, dan penamaan harus dilanjutkan.

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    UPDATE /numbers/1

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:

GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile
TiggerToo
sumber
4

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:

Direktori dapat berisi banyak file dan / atau sub-direktori, dan karenanya namanya harus dalam bentuk jamak.

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/123dapat juga diakses melalui /resource/123, tetapi yang pertama masih harus ada!

Narf
sumber
3

Silahkan lihat pada Google 's API Design Guide: Nama Sumber Daya untuk take lain pada sumber daya penamaan.

Pendeknya:

  • Koleksi diberi nama dengan bentuk jamak.
  • Sumber daya individual diberi nama dengan string.
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /[email protected] | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

Bacaan yang bermanfaat jika Anda memikirkan hal ini.

Shannon Matthews
sumber
2

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. .

Paulo Merson
sumber
1
Ini bukan argumen bagi saya karena Postman menawarkan koleksi, sehingga Anda dapat menyimpan semua sumber daya sebagai item koleksi yang berbeda dan mengujinya secara individual. Yang Anda lakukan hanyalah memilih sumber daya dari koleksi, Anda tidak perlu mengedit parameter / metode / dll setiap kali.
Wirone
1

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.

interface User {
    <string>id;
    <Friend[]>friends;
    <Manager>user;
}

interface Friend {
    <string>id;
    <User>user;
    ...<<friendship specific props>>
}

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 global
  • POST /users - membuat pengguna baru dalam koleksi pengguna global
  • GET /users/{id} - mengambil pengguna tertentu dari koleksi pengguna global
  • GET /users/{id}/manager - dapatkan pengelola pengguna tertentu
  • GET /users/{id}/friends - dapatkan daftar teman pengguna
  • GET /users/{id}/friends/{friendId} - dapatkan teman pengguna tertentu
  • LINK /users/{id}/friends - tambahkan asosiasi teman ke pengguna ini
  • UNLINK /users/{id}/friends - hapus asosiasi teman dari pengguna ini

Perhatikan 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/123tidak meninggalkan indikasi bahwa menciptakan sumber daya baru harus dilakukan diPOST /resources

Steve Buzonas
sumber
1

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:

GET  /resources     =     GET  /resource
GET  /resources/1   =     GET  /resource/1
POST /resources/1   =     POST /resource/1
...

Anda mendapatkan fotonya. Tidak ada yang salah, usaha minimal, dan klien akan selalu melakukannya dengan benar.

Kemenangan
sumber
1
Jika Anda melakukan 302 pengalihan dan cache Anda menyimpan semuanya dua kali, Anda salah mengatur cache. Cache tidak seharusnya menyimpan 302 redirect.
Wynnset
2
Jika klien Anda selalu menggunakan /resourcesdan 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.
maaartinus
Tidak yakin dengan apa yang Anda maksud "salah" - itu sangat subjektif. Itu tidak benar-benar salah karena berhasil.
Wynnset
Ini meningkatkan biaya perawatan, dan biaya pemahaman, dan jumlah kode yang diperlukan.
Will Sheppard
1

Saya tidak suka melihat {id}bagian dari URL tumpang tindih dengan sub-sumber daya, karena secara idteoritis bisa menjadi apa saja dan akan ada ambiguitas. Ini menggabungkan konsep yang berbeda (pengidentifikasi dan nama sub-sumber daya).

Masalah serupa sering terlihat dalam enumkonstanta atau struktur folder, di mana konsep berbeda dicampur (misalnya, ketika Anda memiliki folder Tigers, Lionsdan Cheetahs, dan kemudian juga folder yang disebut Animalspada 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:

GET  /user             -> Not allowed, 400
GET  /user/{id}        -> Returns user with given id
POST /user             -> Creates a new user
PUT  /user/{id}        -> Updates user with given id
DELETE /user/{id}      -> Deletes user with given id

Lalu ada sumber daya terpisah untuk melakukan kueri pada pengguna, yang umumnya mengembalikan daftar:

GET /users             -> Lists all users, optionally filtered by way of parameters
GET /users/new?since=x -> Gets all users that are new since a specific time
GET /users/top?max=x   -> Gets top X active users

Dan di sini beberapa contoh sub-sumber daya yang berhubungan dengan pengguna tertentu:

GET /user/{id}/friends -> Returns a list of friends of given user

Buat teman (banyak ke banyak tautan):

PUT /user/{id}/friend/{id}     -> Befriends two users
DELETE /user/{id}/friend/{id}  -> Unfriends two users
GET /user/{id}/friend/{id}     -> Gets status of friendship between two users

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 ids, secara teoritis memungkinkan untuk memiliki pengguna dengan id newtanpa tumpang tindih dengan nama sub-sumber daya (potensial masa depan).

john16384
sumber
1

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 /usersbenar-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 misalnya user/phone-listatau /user/mailing-list.

Dan bagaimana dengan Pengguna 300? Itu masih /user/300.

GET /user/index
GET /user/{id}

POST /user
PUT /user/{id}

DELETE /user/{id}

Sebagai penutup, HTTP hanya dapat memiliki satu respons terhadap satu permintaan. Jalan selalu merujuk pada sesuatu yang tunggal.

Samuel Danielson
sumber
-1

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_itemsatau cart/itemsterasa benar. Sebaliknya menghapus cart, menghapus objek gerobak itu sendiri dan bukan item dalam gerobak;).

pembuat kode pedesaan
sumber
Bukankah seharusnya ini dibagi / cart dan / cart / item? Kemudian Anda dapat mengatasi seluruh keranjang (mis. Dengan penghapusan) atau item individual?
Rob Grant
@RobertGrant Bukankah itu "/ gerobak / barang / 123"? (mis. mengapa "gerobak" dan bukan "gerobak" adalah aturannya 'selalu jamak'?)
user2864740
1
Saya berpendapat bahwa jika kode produksi dicentang yang dapat melakukan penghapusan item keranjang semua orang, ada masalah yang lebih besar daripada konvensi penamaan. Kemungkinan tudung yang mereka ingat dan miliki di atas ID jauh lebih sedikit.
Andrew T Finnell
Adakah yang akan membuat titik akhir yang hanya menghapus seluruh koleksi? Tampaknya sangat berbahaya bagi saya, dan mungkin juga mengapa REST tidak benar-benar mendukung penghapusan batch. (Anda harus membungkus array menjadi objek). Jika saya benar-benar membutuhkan titik akhir untuk menghapus seluruh koleksi, saya akan memastikan bahwa URI sangat sangat unik, dan jelas tidak mirip dengan POST
cnps
-1

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".

chrisyue
sumber
-2

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:

GET /resources?Id=123

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:

GET /resource?Id=123

server kemungkinan besar akan mengembalikan kesalahan karena ID tidak ditentukan dengan cara yang benar, dan pengguna harus menyadari bahwa ada sesuatu yang salah.

pberggreen
sumber
1
Mengapa kamu mencampur idiom di sini? Anda menggunakan notasi URI yang tepat di paragraf pertama dan kemudian beralih ke parameter kueri? Menggunakan parameter kueri untuk mendapatkan sumber daya dengan ID 123 sepenuhnya berbasis di sini.
Andrew T Finnell
Itu jelas sebuah kesalahan. Saya telah memperbarui jawaban saya sekarang. Terima kasih telah memperhatikannya.
pberggreen
Setelah diturunkan lagi, saya melihat apa yang saya tulis dan saya menyadari bahwa tulisan aslinya benar. Maksud saya adalah bahwa jika pengguna melakukan hal yang salah, maka menggunakan jamak + singular sebenarnya akan memberikan pesan kesalahan yang lebih baik yang menggunakan jamak saja.
pberggreen
Saya masih merasa ini membingungkan masalah yang ada. Gagasan menggunakan jamak adalah bahwa itu adalah koleksi. Dan angka pada akhirnya adalah indeks ke dalam koleksi. Bagaimana jika Anda MENDAPATKAN / sumber daya sendiri? Menggunakan keduanya jamak dan tunggal bersama cukup membingungkan. Mengatakan / sumber daya / 123 mengatakan: Dapatkan sumber saya 123 di keranjang sumber daya.
Andrew T Finnell