REST URI kuralı - Oluştururken kaynağın tekil veya çoğul adı


529

REST'te yeniyim ve bazı RESTful hizmetlerinde güncelleme / alma / silme ve Oluşturma için farklı kaynak URI kullandıklarını gözlemledim. Gibi

  • Oluşturmak - kullanan / kaynaklar kullanarak bazı yerlerde POST yöntemi (çoğul dikkat edin) ile / kaynak (tekil)
  • Güncelleme - PUT yöntemiyle / resource / 123 kullanma
  • Get - GET yöntemiyle / resource / 123 kullanma

Bu URI adlandırma kuralı hakkında biraz kafam karıştı. Kaynak oluşturmak için çoğul veya tekil ne kullanmalıyız? Buna karar verirken kriterler ne olmalı?


9
Bu konuyu takiben, bir makalede ünlü REST API'lerinden birkaç örnek topladım : inmensosofa.blogspot.com/2011/10/… .
jjmontes

3
Aşağıdaki tüm cevapları okuduktan sonra ulaştığım sonuç: Her zaman tekil kullanın çünkü (a) tutarlı, (b) doğrudan tekil sınıf ve tablo adlarıyla eşleşir, (c) bazı çoğul isimler İngilizce düzensizdir (öngörülemez)
Will Sheppard

Tekil tablo adlandırma kurallarına bir bağlantı için bu cevaba bakın ve bu tam sayıdan bahseden başka bir makale var Rest API Geliştiricisinin İkilemi - teşekkür ederim @Sorter
Will Sheppard

Yanıtlar:


281

Kullanmanın temeli, /resources"tüm" kaynakları temsil etmesidir. Bir yaparsanız GET /resources, büyük olasılıkla tüm koleksiyonu döndürürsünüz. Adresine POST yaparak /resources, koleksiyona ekliyorsunuz.

Ancak, bireysel kaynaklar / resource adresinde bulunabilir. Bunu yaparsanız GET /resource, büyük olasılıkla hata yaparsınız , çünkü bu istek bir anlam ifade etmiyor, oysa /resource/123mükemmel bir anlam ifade ediyor.

Kullanma /resourceyerine /resourcessen söz hakkından, bir dosya sistemi ve dosyalar koleksiyonu, çalışmak ve sanki bunu nasıl benzer /resourcebireysel ile "dizin" dır 123, 456o dosyalara.

Her iki şekilde de doğru ya da yanlış, en çok sevdiğiniz şeyle gidin.


55
Mükemmel cevap! Ancak Windows'daki "varsayılan" dizinlerin çoğul adları vardır. "Program Dosyaları", "Kullanıcılar", "Belgeler", "Videolar" gibi. Ayrıca web sitesi url'lerinde birden çok adla daha sık karşılaştım.
Dmitry Gonchar

50
defacto konvansiyonu hemen hemen çoğu insan ve API'leri her zaman çoğul tutmaktır. ID'ler ONE kaynak aracını / kimliğini
PositiveGuy

205
"Her iki şekilde de doğru ya da yanlış, en çok sevdiğin şeyle git." Ah sık sık duyduğum ünlü insanlardan duymaktan yoruldum. Sözleşmeler önemlidir ve topluluk arasında yapıcı bir şekilde tartışılmalıdır, daha iyi çözümler ve iyi uygulamalar ortaya çıkar. URI'lerde kaynak adları için hem çoğul hem de tekil kullandığınızda, kodunuzu ve API'yı karmaşık hale getirir, çünkü API'nin arkasındaki kullanıcı ve kod, tekli çoğul ile tekil arasındaki farkı ayırt etmek için rotalarda ve mantıkta bunu hesaba katmalıdır. her zaman çoğul ile hiçbir sorun var.
PositiveGuy

30
@TomaszPluskiewicz Müşterilerin umursamaması konusunda tamamen haklısınız . Gibi yazılım geliştiricilerinin biz gereken bakım - ve WTF yorumuna katılıyorum bunun için kongre hakkında yapıcı tartışmalar değerli olduğu.
Travis D

12
Birisi sadece tek kelimelik bir cevap koyabilir ve kabul edebilir mi, böylece hepsini tekrar okumak zorunda kalmam.
Ben George

623

Benim için doğrudan kodla eşleştirebileceğiniz (otomatikleştirilmesi kolay) bir şemaya sahip olmak daha iyidir, çünkü kod her iki uçta da olacak.

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) 

22
Bunun zorluğu veya kolaylığı, HATEOS'a saygı göstermemesinden kaynaklanmaktadır. Çoğul mu yoksa tekil mi yoksa başka bir şey mi olduğu önemli değil. Sunucudan gönderilen uri'lere saygı duymalısınız ve uri'nizi istemcide "oluşturmayın". Ardından, kodunuz için 0 eşleme yapmanız gerekir.
richard

7
@richard İstemci hala eşleme yapmak zorundadır. HATEOS'ta URI inşaatı ile ilişkisini (rel) temsil eden bir adla eşlemeleri gerekir. Rel, method (verb) ve Content-Type kaynak medyasını oluşturur. Bu, iyi bir URI tasarımı ihtiyacını engellemez. İstemci rel adına öncelik verebilse de, API geliştiricileri URI yapımı için hala iyi okunabilir bir standarda ihtiyaç duyarlar.

4
Bence bu daha iyi bir cevap. Bunun dışında hep çoğul yerine Singular kullanmayı tercih ettim. User.getList (), User.getById, User.delete vb.
Doğu Keşiş

3
Basitliği seviyorum. Haritalama ayrıca rotalarda yazılması inanılmaz derecede kolay dokümantasyon ve testler yapma avantajına sahiptir.
delos

5
Bu bana mantıklı geliyor. Ancak, veritabanında bir ilk mağazayız, yani veritabanı şemamızdan kod ve api varlıkları üretiyoruz. Ve veritabanı standartları tekil tablo adlarını savunma eğilimindedir, bu yüzden bununla devam ediyoruz, ancak yine de bu cevapla aynı mantık altındayız.
André C. Andersen

274

Bunu da yapmanın nedenini görmüyorum ve bunun en iyi URI tasarımı olmadığını düşünüyorum. RESTful hizmetinin bir kullanıcısı olarak, listeye veya listede 'belirli' kaynağa erişiyor olsam da liste kaynağının aynı ada sahip olmasını beklerdim. Liste kaynağını veya belirli bir kaynağı kullanmak isteyip istemediğinize bakmaksızın aynı tanımlayıcıları kullanmalısınız.


69
Bu benim için en iyi cevap. API tasarımcılarının "123 numaralı kaynağı al" demenin dilsel doğruluğu gibi olduğunu takdir ediyorum, ancak API'nın istemcilerini ve yardım belgelerini yazarken ekstra kodlama zorluğu. (GET / api / people vs. GET / api / person / 123? Euuuchh.) .... "kaynak # 123" gibi düşünmek yerine, kafanızda "kaynakların toplanmasından alın" # 123 "ile eşleşir.
Warren Rumak

5
Çoğul / tekil kaynakları ayırt etmek dilsel doğrulukla değil ölçekle ilgilidir. / Çalışanlar / 12, bana '12' kimliğine sahip çalışanlar kaynağının alt kümesi olarak okur (bu, herhangi bir şey anlamına gelebilir, örneğin yakın zamanda işlenen çalışanlara kaydedilmiş bir arama sorgusu anlamına gelebilir). Yukarıdakileri '12' kimliğine sahip çalışan olarak okursanız, alt kümesi nasıl temsil edersiniz? Tek seçenek, URI'nin nesneleri içeren koleksiyonları nesnelerin kendilerinden (yani tekil veya çoğul) ayırt etmesini sağlamaktır.
Erik

9
Son zamanlarda ateşlenen çalışanlar (veya herhangi bir alt küme) üzerinde bir arama sorgusunu temsil etmek için / çalışanların / 12'nin seçilmesinin kötü tasarım olacağını düşünüyorum. Daha farklı herhangi bir alt kümeyi temsil etmek istiyorsanız, bunları kendi başlarına kaynak (uygun adlarla) olarak tanıtmanızı öneririm.
Jan Deinhard

3
Bunun müşteriler için anlaşılabilirlikle bir ilgisi yoktur. Farklı URL'lerle farklı şeyleri ele almakla ilgilidir. Ve tüm HTTP yöntemlerine uyuşmazlık olmadan yanıt verebilmek. Bir öğe koleksiyonu olan bir kaynağa ve bir öğenin kendisini temsil eden bir kaynağa sahip olabilirsiniz. Herkes için umarım koleksiyon kaynağı example.org/166316e2-e1ve bu koleksiyondaki belirli bir öğe example.org/20d68348-ccc-001c4200de olabilir . İstemci URL'leri oluşturmamalıdır (bu açık bir şekilde ölçeklenmez, RESTful değildir ve bağlantı ilişki türleri bunun içindir).
Erik

4
Rastgele URL'lerin güzel olduğunu düşünmüyorsanız, birden çok ada sahip bir koleksiyon kaynağı ve tekil ada sahip tek bir öğe tanımlamaktan çekinmeyin. İngilizce URL'lerden hoşlanmıyorsanız ve doğal diliniz singualr / çoğul gösterim biçimini, tercih ettiğiniz dilde tanımlamak için başka bir şey kullanmıyorsa, tüm dillerin bir şekilde '/ the-collection-of- bla / 2321 'verson' bla / 61 'yazılı. Ve bu iki farklı kaynağın her biri GET / PUT / DELETE / POST / PATCH ve diğerleri gönderilirken tamamen farklı sonuçları temsil eder.
Erik

77

Çoğul

  • Basit - tüm URL'ler aynı önekle başlar
  • Mantıksal - orders/siparişlerin bir dizin listesini alır.
  • Standart - En yaygın kabul gören standart ve bunu takiben genel ve özel API'lerin büyük çoğunluğu.

Örneğin:

GET /resources - kaynak öğelerinin bir listesini döndürür

POST /resources - bir veya daha fazla kaynak öğesi oluşturur

PUT /resources - bir veya daha fazla kaynak öğesini günceller

PATCH /resources - bir veya daha fazla kaynak öğesini kısmen günceller

DELETE /resources - tüm kaynak öğelerini siler

Ve tek kaynak öğeleri için:

GET /resources/:id- :idparametreye dayalı olarak belirli bir kaynak öğe döndürür

POST /resources/:id - belirtilen kimliğe sahip bir kaynak öğesi oluşturur (doğrulama gerektirir)

PUT /resources/:id - belirli bir kaynak öğeyi günceller

PATCH /resources/:id - belirli bir kaynak öğeyi kısmen günceller

DELETE /resources/:id - belirli bir kaynak öğeyi siler

Tekil savunucuları için şunu düşünün: Birinden orderbir şey ister ve bir şey mi yoksa bir şeyler listesi mi beklerdiniz? Öyleyse neden bir servisin yazarken bir şeyler listesi döndürmesini beklersiniz /order?


10
Tekil : Sisteminizin bir kısmı yalnızca bir nesne olduğunda (0-1, var ya da yok), örneğin kullanıcılar / 1 / avatar Bu tek nesneyi etiketlemek için tekil form kullanabilirsiniz (örneğin avatar) - burada daha ayrıntılı örnek: stackoverflow .com / a / 38296217/860099 . BTW - çok güzel cevap :)
Kamil Kiełczewski

Tekil olması gereken sınıf ve tablo adlarına eşleme yapmaya ne dersiniz? ( diğer cevaba bakınız )
Will Sheppard

@WillSheppard - Sınıf isimleri tekil formda en iyisidir ve tablo isimleri çoğul formda en iyisidir. Örneğin Order, bir siparişe atıfta bulunan nesnelerin tekil örnekleriyle ilgilenen bir sınıf için iyi bir isimdir. OrderListbirden çok Orderörnekle ilgilenen bir sınıfın adıdır . Orders Tablebirçok siparişin veritabanı tablosu için iyi bir isimdir.
Eric Knudtson

GET / sipariş almak istiyorum ama sadece istiyorum / 1
jim smith

@ jim-smith neden GET / users / 1 kullanıcı grubundan / 1 istemiyorsunuz?
Rohmer

49

Tekil

Kolaylık Şeyler düzensiz çoğul isimlere sahip olabilir. Bazen bir tane olmaz. Ancak Singular isimleri her zaman oradadır.

örneğin, Müşteri Adresleri Üzerinden Müşteri Adresi

Bu ilgili kaynağı düşünün.

Bu /order/12/orderdetail/12daha okunabilir ve mantıklı /orders/12/orderdetails/4.

Veritabanı Tabloları

Kaynak, veritabanı tablosu gibi bir varlığı temsil eder. Mantıksal tekil bir adı olmalıdır. İşte tablo isimleri üzerine cevap .

Sınıf Eşleme

Sınıflar daima tekildir. ORM araçları, sınıf adlarıyla aynı adlara sahip tablolar oluşturur. Giderek daha fazla araç kullanıldıkça, tekil isimler bir standart haline geliyor.

A REST API Developer's Dilemma hakkında devamını oku


39
Tekil isimler her zaman oradadır /clothe/12/trouser/34 :)
Gert Arnold

18
@GertArnold kelimesi clothebir fiildir. Dinlenme API'leri genellikle kaynaklar hakkında konuşurken adlara yapışır ve eylemleri açıklarken fiilleri kullanır. Tekil form clout, ancak arkaiktir ve muhtemelen daha uygun bir şekilde yerini alacaktır garment.
Steve Buzonas

@SteveBuzonas Pantolon ve güneş gözlüğü için mi?
Koray Tugay

32

En yaygın uygulama, çoğulların kullanıldığı RESTful apis iken, /api/resources/123tekil bir ismin kullanımını çoğul isimlerden daha uygun / ifade edici bulduğum özel bir durum vardır. Birebir ilişkiler söz konusudur. Özellikle, hedef öğe bir değer nesnesiyse (Etki alanına dayalı tasarım paradigmasında).

Her kaynağın accessLogbir varlık nesnesi olarak modellenebilecek bire bir olduğunu varsayalım . Olarak ifade edilebilir /api/resources/123/accessLog. Her zamanki fiiller (POST, PUT, DELETE, GET), niyetin ve ilişkinin gerçekten birebir olduğu gerçeğini uygun bir şekilde ifade eder.


4
İyi deneme. Ancak "accessLogEntries" olarak daha iyi olurdu. :-)
Tom Russell

8
@TomRussell neden? Bunun sonuçları önemlidir. Bir kaynağa bir tanımlayıcıyla eriştiğinizde bile neden çoğul kullanacağınızı anlıyorum, ancak bire bir veya bire bir için oldukça yanıltıcı. Çok konumlu bir şirketin personelini yöneten bir API'yi düşünün. Her personel bir yerde çalışır. GET /users/123/locationkullanıcının çalıştığı konumu getirmelidir. GET /users/123/locationsTüketici olarak gerçekten yanıltıcı değil mi?
Carrie Kendall

1
@CarrieKendall Demek istediğini anlıyorum. Bu yana accessLogbir öznitelik, veya değeri olarak modellenmiştir yerine bir varlık daha tekil olmalıdır. Fazla mühendislik yapıldıysa, bir günlük girişi bir varlık olur ve sahip olursunuz /api/accessLogEntries?resource=123.
Tom Russell

Anlaşılan, ancak, her şeyi çoğullaştırmak kuralını bozduğunu düşünüyorum. Zor bir iş. Benim için, bir API'nin doğrudan doğru olması önemlidir, yani belgeler zaten basit bir uygulamaya iltifat etmelidir.
Carrie Kendall

Ben bir sistem veya veritabanı kişi daha bir programcı değilim, bu yüzden konvansiyon yerine bir hikaye anlatan bir API seviyorum. Bununla birlikte, otomatik dokümantasyonun etkileri gerçektir.
Tom Russell

26

Neden tekil bir formun genel olarak kabul edildiği veritabanı tablosu adlarının yaygın eğilimini takip etmiyorsunuz? Orada bulundum, bunu yapalım - yeniden kullanalım.

Tablo Adlandırma İkilemi: Tekil ve Çoğul İsimler


8
Das Auto, Die Autos'tan çok daha iyi. Ayrıca, İngilizce çoğul sözleşmeler tutarlı değildir.
FlavorScape

7
Kaynak ad alanı uygulama değil, anlambilim meselesidir. Yani, DB tabloları benzetmesini kullanmak, çok şanslı değildir. Ayrıca DB-s ile çalışırken sadece tabloları yönetiyorsunuz, ancak elbette içeriği (satırları) etkileyebilirsiniz, ancak REST'te tek bir kaynağı doğrudan değiştirmek için herhangi bir kısıtlama yoktur .
arpadf

3
Bunun iyi bir benzetme olduğunu düşünüyorum, ancak tekil veya çoğulculuk yapmaya karar vermekten daha önemli olan hangisini seçerseniz seçin. Kullanıcılar'a eklemeyecek ve ardından Kullanıcı'dan seçmeyeceksiniz. REST kaynakları için de aynı kural geçerlidir - yaptığınız şeye bağlı olarak bunları yeniden adlandırmayın.
Todd Menier

3
Sadece tablo isimleri değil, OO'daki sınıf isimleriyle de karşılaştırılabilir (benim sınıfım Müşteriler değil Müşteri olarak adlandırılacaktı).
bytedev

Bu durumda, anlambilim "zaten tanımlanmış" eğilimleri kabul etmek için çok önemlidir
Cattani Simone

19

Bu kadar çok insanın çoğul isim bandwagonuna atlayacağını görmek beni şaşırttı. Tekil çoğul dönüşümleri uygularken, düzensiz çoğul isimlerle ilgileniyor musunuz? Acıdan hoşlanıyor musunuz?

Bkz. Http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm

Birçok düzensiz çoğul türü vardır, ancak bunlar en yaygın olanlarıdır:

İsim türü Çoğul oluşturma

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)

5
Buradaki endişeyi anlamıyorum. Programlı olarak tekil çoğul olarak değiştirilmememiz gerekiyor. Yukarıdaki çoğul formların çoğu iyi bilinmektedir ve endişe verici olmamalıdır. Birisi iyi İngilizce bilgisine sahip değilse, değişkeninizin herhangi bir bölümünü yanlış heceleyecektir. Ayrıca, mantığınıza bakarak, kaynak kodundaki koleksiyonlara da başvurmak için tekil formlar kullanmanızı da önerir misiniz?
kishor borat

1
İngilizcede bile genellikle sorun olduğu noktaya düzensiz olan İngilizce kelimeler vardır ve bunlar genellikle dizin / dizinler / dizinler, vertix / vertixes / vertices, matris / matrisler / matrisler, yarıçap / yarıçaplar / yarıçap, vb. REST yollarını çoğul hale getirmenin ne anlama geldiğini görmüyorum, çünkü eğer hepsi sürekli olarak tekil ise, herkes için daha açıktır.
1919

@kishorborate, Çoğul URI olarak kullanmak, anadili İngilizce olanlar için bile hataya daha açıktır. Barajın da belirttiği gibi, dizin / dizinler / dizinler gibi çoğullar daha fazla sorun yaratıyor. Sayılamayan isimler var. Sayılamayan isimleri çoğullarla karıştırmak başka bir sorundur. Programcıların bunlara daha fazla zaman ayırmasını neden zorlaştırıyorsunuz? Her şey için tekil kullanmanızı öneririm. / {İd} varsa, API tek bir kayıt döndürmelidir. Takip eden bir / {id} yoksa, API koleksiyonu döndürmelidir.
Daming Fu

3
@DamingFu Tekil kaynağın her zaman kendisiyle ilişkilendirilmiş kimliği olmayabilir. Örneğin. / user / {id} / nickName Buna bakarak, nickNames veya tek nickName listesini döndürüp döndürmeyeceği belli değil mi? Bu nedenle, API'lar birden çok form kullandığında daha sezgiseldir. Evet, birkaç kelimenin düzensiz çoğul biçimleri olacaktır. Çoğul formu okuyan biri için sorun değil. Yalnızca API imzasını yazarken sorun var. Ancak bu tür kelimelerin sıklığı yüksek değildir, ayrıca herhangi bir kelimenin çoğul halini bulmak zaman alıcı değildir. API'leri daha sezgisel hale getirmek için kabul etmeliyiz.
kishor borat

15

API tüketicisinin bakış açısından, uç noktalar öngörülebilir olmalıdır.

İdeal ...

  1. GET /resources bir kaynak listesi döndürmelidir.
  2. GET /resource 400 düzeyli bir durum kodu döndürmelidir.
  3. GET /resources/id/{resourceId} bir kaynağı tek bir koleksiyonla döndürmelidir.
  4. GET /resource/id/{resourceId} bir kaynak nesnesi döndürmelidir.
  5. POST /resources toplu iş kaynakları oluşturmalıdır.
  6. POST /resource kaynak yaratmalı.
  7. PUT /resource bir kaynak nesnesini güncellemelidir.
  8. PATCH /resource yalnızca değiştirilen özellikleri göndererek bir kaynağı güncellemelidir.
  9. PATCH /resources yalnızca değişen öznitelikleri göndererek toplu güncelleme kaynaklarını kullanmalıdır.
  10. DELETE /resourcestüm kaynakları silmeli; şaka yapıyorum: 400 durum kodu
  11. DELETE /resource/id/{resourceId}

Bu yaklaşım, en esnek ve zengin özelliklere sahip olmakla birlikte, aynı zamanda geliştirilmesi için en fazla zaman alan yöntemdir. Eğer aceleniz varsa (ki bu her zaman yazılım geliştirme için geçerlidir) sadece bitiş noktanızı resourceveya çoğul halinizi belirtin resources. Tekil formu tercih ederim, çünkü tüm çoğul formlar 's' ile bitmediği için programlı olarak introspekt ve değerlendirme seçeneği sunar.

Tüm bunları söyledikten sonra, en yaygın kullanılan uygulama geliştiricisinin seçtiği sebep ne olursa olsun çoğul formu kullanmaktır. Bu sonuçta seçtiğim rotadır ve popüler apislere bakarsanız githubve twitteryaptıkları budur.

Karar vermek için bazı kriterler şunlar olabilir:

  1. Zaman kısıtlamalarım nelerdir?
  2. Tüketicilerimin hangi işlemleri yapmasına izin vereceğim?
  3. Talep ve sonuç yükü neye benziyor?
  4. Kodumda yansıma kullanabilmek ve URI'yi ayrıştırmak ister miyim?

Yani size kalmış. Ne yaparsanız yapın tutarlı olun.


1
Birden fazla form seçilmiş gibi görünüyor çünkü geliştiriciler tüm kaynakların doğal olarak bazı koleksiyonun bir parçası olduğunu varsayıyorlar. Bununla birlikte, "kabul edilen sözleşme" nin POST /userstek bir kullanıcı oluşturması ve koleksiyona eklenmesi gerektiğini belirtmektedir . Katılmıyorum. tam olarak bir kullanıcı oluşturması gereken bir kullanıcı POST /userslistesi (1 listesi olsa bile) POST /useroluşturmalıdır. Hem çoğul hem de tekil kaynak uç noktalarının birlikte var olamamasının bir nedenini göremiyorum. Farklı davranışları tanımlarlar ve işlevlerinden kimseyi şaşırtmamalıdırlar.
ezmek

Yolda bir kaynak kimliği belirtmek için bir kural yok mu? Eğer öyleyse, yaygın olarak ihmal edilmiş gibi görünüyor. Örneğin, POST users/<id>yeni bir kullanıcı oluşturur.
Tom Russell

1
@TomRussell genellikle sunucu kimliği oluşturur, bu nedenle henüz POST adresine giden kimliği bilmezsiniz.
Alex

3
@TomRussell, istemci yeni bir kaynak oluştururken (bir tür) kimlik belirlediğinde, bunun PUT /users/<id>yerine kullanılması daha yaygındır POST. POST"bunu koleksiyona ekleyin ve kimliği bunun bir parçası olarak belirleyin" yorumuna sahiptir. PUT"bu kaynağı bu kimlikle güncelleyin (veya ekleyin)." Bu ilkenin daha uzun açıklaması için restcookbook.com/HTTP%20Methods/put-vs-post adresine bakın .
Jochem Schulenklopper

Tüm uç noktaları için Çoğul formu kullandıklarından Twitters API ile karşılaştırmanın adil olduğuna inanmıyorum. Aynı Elemanlar için Çoğul ve Tekil'i karıştırmazlar.
Andrew T Finnell

7

İki sentim: zamanlarını çoğuldan tekil veya viceversa değiştirerek geçiren yöntemler CPU döngüleri israfıdır. Eski okul olabilirim, ama zamanımda işler aynı şekilde adlandırıldı. İnsanlarla ilgili yöntemleri nasıl ararım? Hiçbir düzenli ifade, istenmeyen yan etkileri olmayan kişileri ve insanları kapsamaz.

İngilizce çoğullar çok keyfi olabilir ve kodu gereksiz yere tıkarlar. Bir adlandırma kuralına sadık kalın. Bilgisayar dillerinin doğal dili taklit etmekle değil, matematiksel netlikle ilgili olması gerekiyordu.


2
Bu, uç noktaları "otomatik olarak oluşturmaya / değiştirmeye" çalışan kodu ele alır (çoğulluk / tekillik olduğunu ve haritaya girmeyi deneyen birçok kitaplık vardır); ancak bu, açıkça seçilen uç nokta adlarına doğru sözcüğü seçmekten daha fazla uygulanır (nasıl çoğullandığından bağımsız olarak).
user2864740

6

Hem basitlik hem de tutarlılık için tekil form kullanmayı tercih ederim.

Örneğin, aşağıdaki url dikkate alınarak:

/ Müşteri / 1

Müşteriye müşteri koleksiyonu olarak davranacağım, ancak basitlik için koleksiyon kısmı kaldırıldı.

Başka bir örnek:

/ Ekipman / 1

Bu durumda, ekipmanlar doğru çoğul form değildir. Bu nedenle, bir ekipman koleksiyonu olarak ele alınması ve basitlik için koleksiyonu kaldırması, müşteri durumu ile tutarlı olmasını sağlar.


2
POST / müşteri tek müşteriyi değiştirecek gibi geliyor. Tekil kaynak isimlerini kullanmaktaki en büyük üzüntü bu.
Andrew T Finnell

2
@ andrew-t-finnell POST /customerÇok fazla bir şey yapmama gerek yok - tek bir müşteri ekle?
donmutti

Bir Müşteri koleksiyonuna tek bir Müşteri ekler. POST /customerbana themüşteri POST'ing gibi okuyor . Bir Müşteri koleksiyonu değil. Ancak, çoğul ya da çoğul bir tercih olduğunu kabul edeceğim. Diğer Cevapların yaptığı gibi karışık olmadıkları sürece. Bu inanılmaz derecede kafa karıştırıcı olurdu.
Andrew T Finnell

"Müşteriye POST'ing" bu durumda bir anlam ifade etmiyor. POST yer değiştirmez, ekler. Belki POST / müşteri / 1 olsaydı ikilemi görebiliyordum, ama bu bile bir REST perspektifinden fazla bir anlam ifade etmiyor, çünkü ne ekliyorsunuz? Bu / müşteri / 1 / fatura veya / müşteri / 1 / makbuz, vb.
Olacaktır

5

Bir rotadaki kimlik, bir listenin dizini ile aynı şekilde görüntülenmeli ve adlandırma buna göre devam etmelidir.

numbers = [1, 2, 3]

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

Ancak bazı kaynaklar yollarında kimlikleri kullanmaz, çünkü yalnızca bir tane vardır veya bir kullanıcının asla birden fazlasına erişimi yoktur, bu nedenle bunlar listelenmez:

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

4

Adlandırma kurallarıyla, "sadece birini seçip ona sadık kalın" demek genellikle güvenlidir, bu da mantıklıdır.

Bununla birlikte, REST'i birçok kişiye açıklamak zorunda kaldıktan sonra, uç noktaları bir dosya sistemindeki yollar olarak temsil etmek , bunu yapmanın en etkileyici yoludur.
Vatansız (dosyalar var ya da yok), hiyerarşik, basit ve tanıdık - yerel veya http yoluyla statik dosyalara nasıl erişeceğinizi zaten biliyorsunuz.

Ve bu bağlamda, dilbilimsel kurallar sizi yalnızca aşağıdakilere kadar ulaştırabilir:

Bir dizin birden fazla dosya ve / veya alt dizin içerebilir ve bu nedenle adı çoğul biçimde olmalıdır .

Ve bundan hoşlandım.
Öte yandan - bu sizin dizininiz, istediğiniz gibi ise "a-resource-or-multip-resources" olarak adlandırabilirsiniz. Bu gerçekten önemli bir şey değil.

Önemli olan, "resourceS" adlı bir dizinin altına "123" adlı bir dosya koyarsanız (bunun sonucunda /resourceS/123), dosyaya erişilebilir olmasını bekleyemezsiniz /resource/123.

O anda olması gerekenden daha akıllı yapmaya çalışmayın - şu anda erişmekte olduğunuz kaynak sayısına bağlı olarak çoğuldan singluar'a geçmek bazılarına estetik olarak hoş gelebilir, ancak etkili değildir ve bir sıradüzensel sistem.

Not: Teknik olarak, "sembolik bağlantılar" oluşturabilirsiniz, böylece /resources/123buna da erişilebilir /resource/123, ancak eski hala var olmalıdır!


3

Göz at Google 'ın Kaynak Adları: API Tasarım Rehberi adlandırma kaynaklardaki başka üstlenmek için.

Kısacası:

  • Koleksiyonlar çoğul adlarla adlandırılır.
  • Bireysel kaynaklar bir dize ile adlandırılır.
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /name@example.com | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

Bu konuyu düşünürseniz okumaya değer.


2

Tüm yöntemler için çoğul kullanımı en azından bir açıdan daha pratiktir: Postman (veya benzer bir araç) kullanarak bir kaynak API'sı geliştirip test ediyorsanız, GET'ten PUT'a ve POST'a geçiş yaparken URI'yi düzenlemeniz gerekmez. .


1
Postman koleksiyonlar sunduğundan benim için bir argüman değil, böylece tüm kaynakları farklı koleksiyon öğeleri olarak kaydedebilir ve ayrı ayrı test edebilirsiniz. Tek yapmanız gereken toplamadan kaynak seçmek, parametreleri / yöntemleri / vb. Her zaman düzenlemek zorunda değilsiniz.
Wirone

1

Her iki gösterim de yararlıdır. Kolaylık için oldukça uzun bir süre tekil kullanmıştım, bükülme zor olabilir. Kesinlikle tekil REST API'leri geliştirme deneyimim, uç noktayı tüketen geliştiriciler, sonucun şeklinin ne olacağından emin değiller. Şimdi cevabın şeklini en iyi tanımlayan terimi kullanmayı tercih ediyorum.

Tüm kaynaklarınız üst düzey ise, tekil temsillerden kurtulabilirsiniz. Bükülmeden kaçınmak büyük bir kazançtır.

İlişkilerle ilgili sorguları temsil etmek için herhangi bir derin bağlantı yapıyorsanız, API'nıza karşı yazan geliştiricilere daha katı bir kongre yapılarak yardımcı olabilirsiniz.

Benim kuralım, bir URI'deki her derinlik düzeyinin ana kaynakla bir etkileşimi tanımlaması ve tam URI'nin neyin alındığını örtük olarak tanımlaması gerektiğidir.

Aşağıdaki modele sahip olduğumuzu varsayalım.

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

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

Bir istemcinin belirli bir kullanıcının belirli bir arkadaşının yöneticisini almasına izin veren bir kaynak sağlamanız gerekirse, şöyle görünebilir:

GET /users/{id}/friends/{friendId}/manager

Aşağıda bazı örnekler verilmiştir:

  • GET /users - küresel kullanıcı koleksiyonundaki kullanıcı kaynaklarını listeleyin
  • POST /users - global kullanıcılar koleksiyonunda yeni bir kullanıcı oluşturun
  • GET /users/{id} - küresel kullanıcı koleksiyonundan belirli bir kullanıcıyı alma
  • GET /users/{id}/manager - belirli bir kullanıcının yöneticisini edinin
  • GET /users/{id}/friends - bir kullanıcının arkadaşlarının listesini al
  • GET /users/{id}/friends/{friendId} - bir kullanıcının belirli bir arkadaşını edinin
  • LINK /users/{id}/friends - bu kullanıcıya arkadaşlık ilişkisi ekle
  • UNLINK /users/{id}/friends - bu kullanıcıdan bir arkadaş ilişkilendirmesini kaldır

Her seviyenin, üzerinde işlem yapılabilecek bir ebeveyne nasıl eşlendiğine dikkat edin. Aynı nesne için farklı ebeveynlerin kullanılması mantıksızdır. Adresinde bir kaynağın geri getirilmesi, GET /resource/123yeni bir kaynak oluşturmanınPOST /resources


1

Çoğu insanın çoğul mu yoksa tekil mi kullanacağına karar vermek arasında olduğunu biliyorum. Burada ele alınmayan sorun, müşterinin hangisini kullandığınızı bilmesi gerekeceğidir ve her zaman bir hata yapma olasılığı vardır. Benim önerim buradan geliyor.

Her ikisine de ne dersiniz? Böylece, tüm API'nız için tekil kullanın ve daha sonra çoğul biçimde yapılan istekleri tekil forma iletmek için yollar oluşturun. Örneğin:

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

Resmi aldınız. Kimse yanlış değil, minimum çaba ve müşteri her zaman doğru olacaktır.


1
302 yönlendirmeleri yapıyorsanız ve önbelleğiniz her şeyi iki kez saklıyorsa önbelleğinizi yanlış ayarladınız. Önbelleğin 302 yönlendirmesi depolaması gerekmez.
wynnset

2
İstemciniz her zaman kullanır /resourcesve her zaman yönlendirilirse /resource, yanlış yaptınız. Başka biri API'nizi kullanıyorsa, doğru URL'yi doğrudan kullanabilir veya yönlendirilebilir (bu çalışır, ancak yanlıştır) ve yanlış şekilde açılan sizsiniz.
maaartinus

Ne demek "yanlış" ile emin değilim - bu çok öznel. Gerçekten yanlış değil çünkü işe yarıyor.
wynnset

Bu, bakım maliyetini, anlama maliyetini ve gerekli kod miktarını artırır.
Will Sheppard

1

{id}URL'lerin bir kısmının alt kaynaklarla örtüştüğünü görmek istemiyorum , çünkü idteorik olarak herhangi bir şey olabilir ve belirsizlik olacaktır. Farklı kavramları (tanımlayıcılar ve alt kaynak adları) karıştırmaktadır.

Benzer sorunlar genellikle görülen enumklasörleri olduğunda, sabitler veya farklı kavramlar (karma örnek içindir yapılar, klasör Tigers, Lionsve Cheetahs, ardından da adlandırılan bir klasör Animalsaynı düzeyde - Bir bir alt kümesidir olarak bu hiç mantıklı diğer).

Genel olarak, bir uç noktanın son adlandırılan kısmının, tek seferde tek bir varlık ile ilgiliyse tekil ve varlıkların bir listesi ile ilgiliyse çoğul olması gerektiğini düşünüyorum.

Tek bir kullanıcıyla ilgilenen uç noktalar:

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

Ardından, genellikle bir liste döndüren kullanıcılarda sorgulama yapmak için ayrı bir kaynak vardır:

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

Ve burada belirli bir kullanıcıyla ilgilenen bir alt kaynak örnekleri:

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

Arkadaş edin (çoktan çoka bağlantı):

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

Asla herhangi bir belirsizlik yoktur ve kaynağın çoğul ya da tekil isimlendirilmesi kullanıcıya ne bekleyebileceğine dair bir ipucudur (liste ya da nesne). idTeorik olarak new(potansiyel gelecek) alt kaynak adıyla örtüşmeden kimliğe sahip bir kullanıcıya sahip olmayı mümkün kılan s üzerinde herhangi bir kısıtlama yoktur .


1

Singular'ı kullanın ve örneğin "Ticaret Rehberi" nde görülen İngilizce sözleşmesinden yararlanın.

Birçok şey bu şekilde okur: "Kitap Çantası", "Köpek Paketi", "Sanat Galerisi", "Film Festivali", "Araba Lotu" vb.

Bu, soldan sağa doğru url yoluna uygundur. Soldaki öğe türü. Türü sağda ayarlayın.

Does GET /usersgerçekten hiç bir kullanıcı grubu getir? Genellikle değil. Bir anahtar ve belki de bir kullanıcı adı içeren bir dizi taslak getirir. Yani gerçekten /usersde değil . Bu bir kullanıcı dizini veya isterseniz bir "kullanıcı dizini" dir. Neden böyle demiyorsun? Bu bir /user/index. Küme türünü adlandırdığımızdan, örneğin user/phone-listveya sorgu parametrelerine başvurmadan bir kullanıcının farklı projeksiyonlarını gösteren birden çok türe sahip olabiliriz /user/mailing-list.

Peki ya Kullanıcı 300? Hala /user/300.

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

POST /user
PUT /user/{id}

DELETE /user/{id}

Kapanışta, HTTP tek bir isteğe yalnızca tek bir yanıt verebilir. Bir yol her zaman tekil bir şeyi ifade eder.


-1

Benim için çoğullar koleksiyonu , tekiller ise bu koleksiyonun içindeki öğeleri manipüle ederler .

Koleksiyon , GET / POST / DELETE yöntemlerine izin verir

Öğe GET / PUT / DELETE yöntemlerine izin verir

Örneğin

POST / öğrenciler okula yeni bir öğrenci ekleyecek.

/ DELETE / öğrenciler okuldaki tüm öğrencileri kaldıracak.

/ Öğrenci / 123 üzerindeki SİL, öğrenci 123'ü okuldan kaldıracak.

Önemsiz gibi gelebilir, ancak bazı mühendisler bazen kimliği unutur. Rota her zaman çoğulsa ve bir DELETE gerçekleştirdiyse, verilerinizi yanlışlıkla silebilirsiniz. Oysa tekil kimlikte eksik ise 404 bulunamadı.

API'nın birden fazla okulu ortaya çıkarması gerekiyorsa örneği daha da genişletmek için,

/ Okul / abc / öğrencilerden SİL, okuldaki tüm öğrencileri kaldıracaktır abc.

Doğru kelimeyi seçmek bazen kendi başına bir zorluktur, ancak koleksiyon için çoğulluğu sürdürmeyi seviyorum. Örneğin, cart_itemsya da cart/itemsdoğru geliyor. Buna karşılık silme işlemi cart, sepet nesnesini değil, kendisinin sepet nesnesini siler;).


Bu bölünmüş olmamalı / cart ve / cart / item (ler) zaten? Sonra tüm sepete (örneğin bir silme ile) veya tek tek öğelere hitap edebilirsiniz?
Rob Grant

@RobertGrant "/ carts / items / 123" olmaz mı? (örneğin, "sepeti" ve "arabaları" kuralı neden hep çoğul '.?)
user2864740

1
Herkesin alışveriş sepeti öğelerini silme işlemini yapabilen üretim kodu işaretlenirse, adlandırma kuralından daha büyük sorunlar olduğunu iddia ediyorum. Bir kimlik üzerinde bir 's' hatırladıkları olası başlık çok daha azdır.
Andrew T Finnell

Herkes sadece bir koleksiyonun tamamını silen bir bitiş noktası yaratır mı? Benim için son derece tehlikeli görünüyor ve muhtemelen REST neden toplu silme işlemlerini gerçekten desteklemiyor. (diziyi bir nesneye sarmanız gerekir). Tüm koleksiyonu silmek için kesinlikle bir uç noktaya ihtiyacım olsaydı, URI'nin çok benzersiz olduğundan ve kesinlikle
POST'a benzemediğinden emin olurdum

-1

Nasıl olur:

/resource/(değil /resource)

/resource/ "kaynak" adı verilen bir klasör olduğu, "kaynak" klasörü olduğu anlamına gelir.

Ve ayrıca veritabanı tablolarının adlandırma kuralı aynı olduğunu düşünüyorum, örneğin, 'kullanıcı' adlı bir tablo bir "kullanıcı tablosu", "kullanıcı" adlı bir şey içeriyor.


-2

Hem çoğul ( /resources) hem de tekil (/resource/{id} çünkü kaynakların toplanması üzerinde çalışmak ve tek bir kaynak üzerinde çalışmak arasındaki mantığı daha açık bir şekilde ayırdığını düşünüyorum.

Bunun önemli bir yan etkisi olarak, birisinin API'yi yanlış kullanmasını önlemeye de yardımcı olabilir. Örneğin, bir kullanıcının kimliği Id gibi bir parametre olarak belirterek yanlış bir şekilde kaynak almaya çalıştığı durumu düşünün:

GET /resources?Id=123

Bu durumda, çoğul sürümü kullandığımızda, sunucu büyük olasılıkla Id parametresini yok sayar ve tüm kaynakların listesini döndürür. Kullanıcı dikkatli değilse, aramanın başarılı olduğunu düşünecek ve listedeki ilk kaynağı kullanacaktır.

Öte yandan, tekil formu kullanırken:

GET /resource?Id=123

Kimlik doğru şekilde belirtilmediğinden ve büyük olasılıkla kullanıcının bir şeylerin yanlış olduğunu fark etmesi gerekecektir.


1
Neden burada deyimleri karıştırıyorsun? İlk paragrafta uygun URI gösterimini kullanın ve sonra sorgu parametrelerine geçiş? 123 kimliğine sahip bir kaynak elde etmek için sorgu parametrelerini kullanmak burada tamamen temel dışıdır.
Andrew T Finnell

Bu açıkça bir hataydı. Cevabımı şimdi güncelledim. Fark ettiğin için teşekkürler.
pberggreen

Tekrar reddedildikten sonra, yazdıklarıma baktım ve orijinal yazının doğru olduğunu anladım. Demek istediğim, kullanıcı yanlış bir şey yaparsa, o zaman çoğul + tekil kullanmak aslında sadece çoğul kullanan daha iyi bir hata mesajı verecektir.
pberggreen

Hala bu konuyu kafa karıştırıcı hissediyorum. Çoğul kullanma fikri, bunun bir koleksiyon olması. Ve sondaki sayı, koleksiyonun bir dizinidir. Kendi başına kaynak / kaynak alırsanız ne olur? Hem çoğul hem de tekil birlikte kullanmak oldukça kafa karıştırıcıdır. / Resources / 123 diyor ki: 123 kaynağımı kaynaklar grubuna alın.
Andrew T Finnell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.