İlk
Başına gibi RFC 3986 §3.4 (Tekdüzen Kaynak Tanımlayıcıları § (sözdizimi Bileşenleri) | Sorgu
3.4 Sorgu
Sorgu bileşeni, yol bileşenindeki verilerle (Bölüm 3.3), URI'nin şeması ve adlandırma yetkisi (varsa) kapsamında bir kaynağı tanımlamaya hizmet eden hiyerarşik olmayan veriler içerir.
Sorgu bileşenleri, hiyerarşik olmayan verilerin alınması içindir; doğada soy ağacından daha hiyerarşik olan çok az şey var! Ergo - “REST-y” olup olmadığını düşünmeden bağımsız olarak - İnternet üzerindeki sistemlerin formatları, protokolleri ve çerçevelerine uymak için ve geliştirmek için sorgu dizesini kullanmamalısınız.
REST'in bu tanımla ilgisi yoktur.
Özel sorularınızı belirtmeden önce, "search" sorgusu parametreniz kötü adlandırılır. Sorgu segmentinize bir anahtar / değer çiftleri sözlüğü gibi davranmak daha iyi olur.
Sorgu dizeniz daha uygun olarak tanımlanabilir
?first_name={firstName}&last_name={lastName}&birth_date={birthDate}
vb.
Özel sorularınızı cevaplamak için
1) Hangi API tasarımı daha RESTful ve neden? Anlamsal olarak, aynı anlama gelir ve aynı şekilde davranırlar. URI'deki son kaynak, "çocuklar" dır ve etkin olarak müşterinin çocuk kaynakları üzerinde çalıştığını ima eder.
Bunun, inandığın kadar açık bir kesim olduğunu sanmıyorum.
Bu kaynak arabirimlerinin hiçbiri RESTful değildir. Majör RESTful mimari tarzı ön koşulu Application State geçişler hypermedia olarak sunucudan iletilmelidir gerektiğidir. İnsanlar URI'lerin yapısını üzerinde bir şekilde "RESTful URI'lar" yapmak için çalıştılar, ancak REST ile ilgili resmi literatürde bu konuda söylenecek çok az şey var. Benim kişisel görüşüm, REST hakkındaki meta-yanlış bilginin çoğunun eski ve kötü alışkanlıkların kırılması amacıyla yayınlandığı yönünde. (Gerçekten "RESTful" bir sistem oluşturmak aslında oldukça fazla bir iştir. Endüstri, "REST" e başvurdu ve bazı ortogonal kaygıları saçma nitelikler ve kısıtlamalar ile geri doldurdu.)
REST literatürünün söylediği şey, HTTP'yi uygulama protokolünüz olarak kullanacaksanız, protokolün şartnamelerinin resmi gerekliliklerine uymanız ve "giderken http yapamazsınız ve hala http kullandığınızı beyan edemezsiniz" dır. ; Kaynaklarınızı tanımlamak için URI'leri kullanacaksanız, URI / URL'lerle ilgili şartnamelerin resmi şartlarına uymalısınız.
Sorunuz doğrudan yukarıda bağlantı kurduğum RFC3986 §3.4'te ele alınmaktadır. Bu konudaki sonuç, uygun bir URI'nin bir API'yi "RESTful" olarak değerlendirmek için yetersiz olmasına rağmen, sisteminizin gerçekte "RESTful" olmasını istiyorsanız ve HTTP ve URI'leri kullanıyorsanız, bu durumda hiyerarşik verileri tanımlayamazsınız. sorgu dizesi çünkü:
3.4 Sorgu
Sorgu bileşeni hiyerarşik olmayan veriler içeriyor
...bu kadar basit.
2) Müşterinin bakış açısından anlaşılabilirliği ve tasarımcının bakış açısıyla bakımı açısından her birinin lehte ve aleyhinde olanlar nelerdir?
İlk ikisinin "artıları" , doğru yolda olmalarıdır . Üçüncü olanın "eksileri" yanlış anlaşılıyor gibi görünüyor.
Anlaşılabilirliğiniz ve bakımınızla ilgili endişeleriniz söz konusu olduğunda, bunlar kesinlikle özneldir ve müşteri geliştiricisinin anlama düzeyine ve tasarımcının tasarım parçalarına bağlıdır. URI belirtimi, URI'lerin nasıl biçimlendirileceği konusundaki kesin cevaptır. Hiyerarşik verilerin yol üzerinde ve yol parametreleriyle temsil edilmesi gerekiyor. Hiyerarşik olmayan verilerin sorguda gösterilmesi gerekiyordu. Parça daha karmaşık, çünkü onun anlambilimi, özellikle talep edilen temsilin medya türüne bağlı. Bu nedenle, sorunuzun "anlaşılabilirliği" bileşenine değinmek için, ilk iki URI'nin gerçekte söylediklerini tam olarak çevirmeye çalışacağım. Ardından, geçerli URI'lerle yapmaya çalıştığınız şeyleri temsil etmeye çalışacağım.
Sözlü URI'larınızın semantik anlamlarına çevirisi
/myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}
Bu, büyükanne ve büyükbabaların ebeveynleri için, çocuklarının URI'nızla söylediklerinizi yalnızca bir büyük ebeveynin search={text}
kardeşlerini ararken tutarlı olduğu anlamına gelir. "Büyükanne ve büyükbaba, ebeveynler, çocuklar" ile, bir "büyükbaba veya büyükbaba" bulduktan sonra ebeveynlerine bir kuşak yükseldi ve sonra ebeveynlerin çocuklarına bakarak "büyükbaba" nesline geri döndüm.
/myservice/api/v1/parents/{parentID}/children?search={text}
Bu, {parentID} tarafından tanımlanan ebeveyne göre, çocuklarının ?search={text}
neyi istediğinizi düzeltmek için daha yakın olduğunu ve sizin tüm API'nizi modellemek için kullanılabilecek bir ebeveyn > çocuk ilişkisini temsil ettiğini söyler. Bu şekilde modellemek için yük, müşteriye "büyük ebeveyn" varsa, sahip oldukları kimlik ile aile grafiğinin görmek istedikleri kısmı arasında bir dolaylı katmanın olduğunu kabul etmek için yüklenir. "GrandparentId" adlı bir "çocuk" bulmak için, /parents/{parentID}/children
hizmetinizi arayabilir ve sonra geri gönderilen her çocuğu arayabilirsiniz, çocuklarını kişi tanımlayıcınız için arayabilir.
Gereksinimlerinizin URI'ler olarak uygulanması
Ağaçta yürüyebilecek daha genişletilebilir bir kaynak tanımlayıcıyı modellemek istiyorsanız, bunu başarabileceğiniz birkaç yol düşünebilirim.
1) İlki, zaten itiraz ettim. Kompozit bir yapı olarak "İnsanlar" grafiğini temsil eder. Her insan, Üstler Arası yolu üzerindeki üstündeki nesile ve Altındaki yolu Alemi yoluyla kendi altına göndermiştir.
/Persons/Joe/Parents/Mother/Parents
Joe'nun anneannesinin dedesini almanın bir yolu olurdu.
/Persons/Joe/Parents/Parents
Joe'nun büyükanne ve büyükbabasını almanın bir yolu olurdu.
/Persons/Joe/Parents/Parents?id={Joe.GrandparentID}
Elinizde olan tanımlayıcıya sahip Joe'nun büyük ebeveynini yakalardı.
ve bunların hepsi bir anlam ifade eder (“Ebeveynler / Ebeveynler / Ebeveynler” modelindeki şube kimliği eksikliği nedeniyle sunucuda bir dfs zorlayarak göreve bağlı olarak burada bir performans cezası olabileceğini unutmayın.) Ayrıca, İstediğiniz sayıda nesli destekleme yeteneği. Herhangi bir sebepten ötürü, 8 nesile bakmak istersen, bunu şu şekilde temsil edebilirsin:
/Persons/Joe/Parents/Parents/Parents/Parents/Parents/Parents/Parents/Parents?id={Joe.NotableAncestor}
ancak bu, bu verileri temsil etmek için ikinci baskın seçeneğe yol açar: bir yol parametresiyle.
2) "hiyerarşi sorgulamak" giden yolun parametreleri kullanın Sen tüketiciler üzerindeki yükü hafifletmek ve hala mantıklı bir API var yardımcı olmak için aşağıdaki yapıyı geliştirebilir.
147 nesiller geriye bakmak için, bu kaynak tanımlayıcıyı yol parametreleriyle temsil etmenizi sağlar
/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor}
Joe’yu Büyük Anne ve Büyükbabası’ndan bulmak için, grafikte Joe’nun kimliği için bilinen sayıda nesiller görebilirsiniz.
/Persons/JoesGreatGrandparent/Children;generations=3?id={Joe.Id}
Bu yaklaşımlarda dikkat edilmesi gereken en önemli şey, tanımlayıcı ve istekte daha fazla bilgi olmadan, ilk URI’nın, Joe’dan Joe tanımlayıcı ile birlikte, nesillerindeki 147 nesli bir Kişi’yi almasıdır. İkincisinin Joe'yu almasını beklemelisin. Gerçekte ne istediğinizi, arayan müşterinizin tüm düğüm kümesini ve bunların kök Kişi ile URI'nizin son bağlamı arasındaki ilişkilerini alabilmesi olduğunu varsayalım. Bunu, aynı URI ile (bazı ek dekorasyonlarla birlikte) ve text/vnd.graphviz
isteğinize göre Kabul et'i ( .dot
grafik gösterimi için IANA kayıtlı ortam türü olan) belirleyerek yapabilirsiniz . Bununla, URI’yi olarak değiştirin.
/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor.Id}#directed
Bir HTTP İstek Başlığı
Accept: text/vnd.graphviz
ile müşterilerinize Joe ve 147 nesiller arasındaki nesiller arası hiyerarşinin yönlendirilmiş grafiğini istediklerini açıkça belirtmelerini sağlayabilirsiniz;
Text / vnd.graphviz 'in parçası için önceden tanımlanmış bir semantiği olup olmadığından emin değilim, talimat aramada hiçbirini bulamadım. Bu ortam türü aslında önceden tanımlanmış parça bilgisine sahipse, uygun bir URI oluşturmak için semantiğinin izlenmesi gerekir. Ancak, bu anlambilim önceden tanımlanmamışsa, URI belirtimi, fragman tanımlayıcısının anlambiliminin sınırsız olduğunu ve bunun yerine sunucu tarafından tanımlandığını belirtir, bu kullanımı geçerli kılar.
3) Kaynağınızdaki "filtrelemenin" yanı sıra gerçekten kullanılan sorgu dizeleri nelerdir? İlk yaklaşıma girerseniz, filter parametresi URI'da sorgu dizesi parametresi yerine path parametresi olarak gömülür.
Bunu zaten ölüme kadar yendiğime inanıyorum, ancak sorgu dizeleri kaynakları "filtrelemek" için değil. Onlar içindir tanımlayan hiyerarşik olmayan verilerden kaynağınız. Eğer giderek yolu ile hiyerarşisinde aşağı delinmiş varsa
/person/{id}/children/
ve bir tespit etmek isteyen vardır spesifik çocuk veya belirli çocukların seti, size tespit ediyorlar grubuna uygulanır bazı özellik kullanmak ve onu sorguya içeride yer alacak.