Aramalar RESTful bir arayüze nasıl uyar?


137

RESTful bir arayüz tasarlarken, talep tiplerinin anlamları tasarım için hayati önem taşır.

  • GET - Koleksiyon listesi veya alma elemanı
  • PUT - Koleksiyon veya öğeyi değiştir
  • POST - Koleksiyon veya öğe oluştur
  • DELETE - Eh, erm, koleksiyon veya öğeyi sil

Ancak, bu "arama" kavramını kapsamıyor gibi görünmüyor.

Örneğin, bir İş Arama sitesini destekleyen bir web servisleri takımı tasarlarken aşağıdaki gereksinimlere sahip olabilirsiniz:

  • Bireysel İş İlanını Alın
    • GET içindomain/Job/{id}/
  • İş İlanı Oluştur
    • POST içindomain/Job/
  • İş İlanını Güncelle
    • PUT içindomain/Job/
  • İş İlanını Sil
    • SİL içindomain/Job/

"Tüm İşleri Al" da basittir:

  • GET içindomain/Jobs/

Ancak, "arama" işi bu yapıya nasıl giriyor?

Bunun bir "liste koleksiyonu" varyasyonu olduğunu iddia edebilir ve aşağıdaki gibi uygulayabilirsiniz:

  • GET içindomain/Jobs/

Ancak, aramalar karmaşık olabilir ve uzun bir GET dizesi üreten bir arama yapmak tamamen mümkündür. Yani, burada bir SO sorusunu referans alarak , yaklaşık 2000 karakterden daha uzun GET dizelerini kullanan sorunlar var.

Bir örnek, yönlü bir aramada olabilir - "iş" örneğine devam ediyor.

Yönleri aramaya izin verebilirim - "Teknoloji", "İş Unvanı", "Disiplin" ve serbest metin anahtar kelimeler, iş yaşı, yer ve maaş.

Akıcı bir kullanıcı arayüzü ve çok sayıda teknoloji ve iş başlığıyla, bir aramanın çok sayıda faset seçimini kapsayabileceği mümkündür.

Bu örneği işlerden ziyade özgeçmişlere yönlendirin, hatta daha fazla faset getirin; seçili yüz fasetli bir aramayı, hatta her biri 50 karakter uzunluğunda olan sadece 40 fasetli bir aramayı kolayca hayal edebilirsiniz (örneğin, İş Başlıkları, Üniversite İsimleri, İşveren İsimleri).

Bu durumda, arama verilerinin doğru bir şekilde gönderilmesini sağlamak için bir PUT veya POST taşımak istenebilir. Örneğin:

  • POST içindomain/Jobs/

Fakat anlamsal olarak bu bir koleksiyon oluşturma talimatıdır.

Sen olabilir ayrıca bir aramanın oluşturulması olarak bu ifade edeceğiz ki:

  • POST içindomain/Jobs/Search/

veya (aşağıda burninggramma tarafından önerildiği gibi)

  • POST içindomain/JobSearch/

Anlamsal olarak mantıklı görünebilir, ancak aslında hiçbir şey oluşturmuyorsunuz, veri talebinde bulunuyorsunuz.

Bu nedenle, anlamsal olarak bir GET'dir , ancak GET'in ihtiyacınız olanı desteklemesi garanti edilmez.

Öyleyse, soru şu - Mümkün olduğunca RESTful tasarıma sadık kalmaya çalışırken, HTTP'nin sınırları dahilinde kalmamı sağlarken, bir arama için en uygun tasarım nedir?


3
Sık sık niyet kullanımı GET domain/Jobs?keyword={keyword} . Bu benim için iyi çalışır :) Umarım, SEARCHfiil standart hale gelecektir. programmers.stackexchange.com/questions/233158/…
Knerd

Evet, önemsiz bir örnek için bir problem olmadığını görebiliyorum. Ancak geliştirdiğimiz araçta, 2000 karakterden daha uzun bir GET dizesiyle sonuçlanan karmaşık bir arama ile sonuçlanmamız inanılmaz bir şey değil. Sonra ne?
Rob Baillie,

Aslında çok iyi bir nokta. Sıkıştırma teknolojisini belirlemeye ne dersiniz?
Knerd

2
Bir gövdeye sahip olan GET'e HTTP spesifikasyonu tarafından izin verilir, ara katman yazılımı (bazen değil);) olabilir veya desteklenmeyebilir veya bu uygulama tarafından tercih edilmez. Bu periyodik olarak Stackexchange'te belirir. stackoverflow.com/questions/978061/http-get-with-request-body
Rob

2
POST JobSearch'un gerçek bir arama öğesi yaratmasını ve bir jobSearchId döndürmesini sağladım. Ardından GET jobs? JobSearch = jobSearchId asıl işler koleksiyonunu döndürür.
Cerad

Yanıtlar:


93

GET taleplerinin diğer çözümlere göre bazı üstün avantajları olduğunu unutmamalısınız :

1) GET istekleri URL çubuğundan kopyalanabilir, arama motorları tarafından sindirilir, "dost" olurlar. "Dostça" ifadesi normalde bir GET isteğinin uygulamanızın içindeki hiçbir şeyi değiştirmemesi gerektiği anlamına gelir (hakem) . Bu bir arama için standart durumdur.

2) Bu kavramların tümü sadece kullanıcı ve arama motorundan değil, aynı zamanda mimari bir API tasarım açısından da önemlidir .

3) POST / PUT ile bir geçici çözüm yaratırsanız , şu anda düşünmediğiniz problemleriniz olacaktır. Örneğin, bir tarayıcı durumunda, geri git düğmesine / sayfayı / sayfayı yenile. Bunlar elbette çözülebilir, ama bu başka bir geçici çözüm olacak, sonra başka bir başka ...

Bütün bunları göz önünde bulundurarak tavsiyem :

a) Eğer içine sığacak gerekir ile GET kullanarak akıllı parametre yapısını . Aşırı durumda, hala çok fazla parametre belirttiğim google search gibi taktiklere bile gidebilirsiniz .

b) JobSearch gibi uygulamanızda başka bir varlık yaratın . Çok fazla seçeneğiniz olduğunu varsayarsak, bu aramaları da saklamanız ve yönetmeniz gerekebilir, bu nedenle uygulamanızı temizler. JobSearch nesneleriyle bir bütün olarak çalışabilirsiniz , yani test edebilirsiniz / daha kolay kullanabilirsiniz .


Şahsen bunu yapmak için tüm pençelerimle savaşmaya çalışacağım a) ve tüm umutlar kaybolduğunda gözlerimdeki gözyaşları ile b) seçeneğine geri döneceğim .


4
Açıklama için, bu sorunun web sitesi tasarımı değil, web hizmetleri tasarımı ile ilgili olması amaçlanmıştır. Dolayısıyla, tarayıcı davranışı, sorunun yorumlanmasının daha geniş kapsamı ile ilgilenirken, açıklanan özel durumda bunun bir sonucu yoktur. (ilginç nokta olsa da).
Rob Baillie

@RobBaillie Ye Tarayıcı sadece bir kullanım durumuydu. Aramanızın bir bütün olarak bir URL dizesiyle temsil edildiğini söylemek istedim. Kullanılabilirlik konusunda çok fazla rahatlığa sahip olan ve daha sonra cevaplarda diğer hususlarla birlikte.
p1100i

B noktasında, bu POST'a atıfta bulunduğum basit bir varyasyon olabilir domain/Jobs/Search/, belki domain/JobsSearch/bunun yerine, yoksa farklı bir şey mi demek istedin? Açıklayabilir misin?
Rob Baillie,

7
Neden REST'in çözümün bir parçası olmaktan çok sorunun bir parçası olduğu izlenimini alıyorum?
JensG

1
"GET isteği, uygulamanızın içindeki hiçbir şeyi (idempotent) değiştirmemelidir", GET idempotent iken, ilgili kelime burada " güvenli " dir. Önemsiz olan, bir kaynağa iki kez GET yapmanın, o kaynak üzerine bir kez GET yapmakla aynı olduğu anlamına gelir. PUT aynı zamanda müstehcen ancak güvenli değildir.
Jasmijn

12

TL; DR: Filtreleme için GET, arama için POST

Karmaşık bir aramaya göre bir koleksiyonu listeleme sonuçlarının filtrelenmesi arasında bir ayrım yapıyorum. Kullandığım litmus testi temelde filtrelemeden (pozitif, negatif veya aralık) daha fazlasına ihtiyacım olursa , POST gerektiren daha karmaşık bir arama olduğunu düşünüyorum.

Neyin iade edileceğini düşünürken, bu güçlenme eğilimindedir. Genellikle yalnızca bir kaynak çoğunlukla tam bir yaşam döngüsüne sahipse (PUT, DELETE, GET, koleksiyon GET) kullanıyorum . Genellikle bir koleksiyonda GET, bu koleksiyonu oluşturan REST kaynakları olan URI'ların bir listesini döndürüyorum. Karmaşık bir sorguda yanıtı oluşturmak için birden fazla kaynaktan çekiyor olabilirim (SQL'e katılmayı düşünüyorum), böylece URI'leri geri göndermeyeceğim, ancak gerçek verileri. Sorun şu ki, veriler bir kaynakta gösterilmeyecek, bu yüzden her zaman veriyi geri vermem gerekecek. Bu bana bir POST gerektiren kesin bir kesinti gibi görünüyor.

-

Bir süre oldu ve orjinal yazım biraz özensiz geçti, bu yüzden güncelleyeceğimi düşündüm.

GET, çoğu veri türünü, REST kaynak koleksiyonlarını, bir kaynağın yapılandırılmış verilerini, hatta tekil yükleri (görüntüler, dokümanlar, vb.) Geri döndürmek için sezgisel bir seçimdir.

POST, GET, PUT, DELETE, vb. İle uyuşmuyor gibi görünen herhangi bir şey için çekici bir yöntemdir.

Bu noktada basit aramalar, filtrelemenin GET üzerinden sezgisel bir anlam ifade ettiğini düşünüyorum. Karmaşık aramalar, özellikle toplama işlevlerine, çapraz korelasyonlara (birleşmelere), yeniden biçimlendiricilere vb. Atıyorsanız kişisel tercihlere bağlıdır. ) genellikle bir POST istek gövdesi olarak daha anlamlı olabilir.

Ayrıca API kullanımının deneyim yönünü de düşünüyorum. Genellikle yöntemlerin çoğunu kullanımı kolay ve sezgisel yapmak isterim. Daha esnek (ve dolayısıyla daha karmaşık) olan çağrıları POST'lara ve farklı bir kaynak URI'sine, özellikle de aynı API'deki diğer REST kaynaklarının davranışlarıyla tutarsız ise zorlayacağım.

Her iki durumda da tutarlılık, GET veya POST'ta arama yapıp yapmadığınızdan muhtemelen daha önemlidir.

Bu yardımcı olur umarım.


1
REST, altta yatan uygulamayı soyutlamak için tasarlandığından (örneğin - bir kaynak mutlaka bir veritabanındaki bir satır veya bir sabit sürücüdeki bir dosya olmak zorunda değildir , ancak herhangi bir şey olabilir ) POST üzerinden kullanımın mutlaka gerekli olduğunu bilmiyorum. SQL birleşmeleri gerçekleştirme konusunda GET. Bir okul masanız ve bir çocuk masanız olduğunu ve bir sınıf (bir okul, birden fazla çocuk) istediğinizi varsayalım. Sanal bir kaynağı kolayca tanımlayabilir ve GET /class?queryParams. Bir kullanıcının bakış açısından "sınıf" her zaman bir şeydi ve herhangi bir garip SQL'e katılmak zorunda kalmadınız.
stevendesu

"Filtreleme" ile "arama" arasında bir fark yoktur.
Nicholas Shanks

1
Evet var, bir filtre mevcut alanlara dayanmaktadır. Bir arama çok daha karmaşık kalıplar içerebilir, alanları birleştirerek, uygun değerleri hesaplayarak vb.
İçerebilir

@stevendesu tam olarak, bu yüzden POST kullanıyorum hem de (bir arama oluşturma) :-)
ymajoros

@ymajoros Arama terimlerini ve aramanın sonuçlarını bir yere kaydetmezseniz, POST'un anlamsal olarak anlamlı olduğunu bilmiyorum. Bilgi isteğinde bulunduğunuz bir arama yaptığınızda, hiçbir yerde saklanacak yeni bilgiler sağlamıyorsunuzdur.
stevendesu

10

REST'te kaynak tanımı çok geniştir. Gerçekten de bazı verileri bir araya getirmek istiyorsun.

  • Bir arama kaynağını bir koleksiyon kaynağı olarak düşünmek faydalıdır. Bazen URI'nin aranabilir kısmı olarak adlandırılan sorgu parametreleri, kaynağı müşterinin ilgilendiği öğelere kadar daraltır.

Örneğin, ana Google URI’sı “İnternet’teki her siteye bağlantı” derleme kaynağına işaret eder. Sorgu parametreleri, görmek istediğiniz sitelere göre daralır.

(URI = evrensel kaynak tanımlayıcısı, bu URL, evrensel kaynak konumlandırıcısı, burada tanıdık "http: //" bir URI için varsayılan biçimdir. Bu nedenle, URL bir konumlandırıcıdır, ancak REST'te bunu bir kaynak tanımlayıcıya genelleştirmek iyidir İnsanlar yine de onları birbirleriyle değiştirir.

  • Örnekte aradığınız kaynak iş koleksiyonu olduğu için, aramaya başlamak mantıklıdır.

Siteyi / işleri al? Type = blah & location = here & etc = etc

(dönüş) {jobs: [{job: ...}]}

Daha sonra, bu koleksiyona yeni öğeler eklemek için ekleme veya işlem fiili olan POST'u kullanın:

POST sitesi / işleri

{iş: ...}

  • jobHer durumda nesne için aynı yapıya sahip olduğuna dikkat edin . Bir müşteri, aramayı daraltmak için sorgu paramlarını kullanarak bir iş koleksiyonu ALABİLİR ve ardından yeni bir işin POST'u için öğelerden biri için aynı formatı kullanabilir. Veya bu öğelerden birini alabilir ve bunu güncellemek için URI'sına çekebilir.

  • Gerçekten çok uzun veya karmaşık sorgu dizeleri için, kural yerine, bunları POST istekleri olarak göndermeyi tamamlar. Sorgu parametrelerini bir JSON veya XML yapısında ad / değer çiftleri veya iç içe geçmiş nesneler olarak toplayın ve isteğin gövdesine gönderin. Örneğin, sorgunuzda bir grup ad / değer çifti yerine iç içe geçmiş veriler varsa. POST için HTTP belirtimi, ekleme veya işlem fiili olarak tanımlanır. (REST'teki bir boşluktan bir savaş gemisine çıkmak istiyorsanız, POST kullanın.)

Yine de bunu geri dönüş planı olarak kullanırdım.

Bunu yaparken ne kaybedersiniz a) GET nullipotent - yani, hiçbir şey değişmez - POST değildir. Bu nedenle, çağrı başarısız olursa, ara katman yazılımı otomatik olarak yeniden denemez veya sonuçları önbelleğe alamaz ve 2) gövdede bulunan arama parametreleriyle, artık URI'yi kesip yapıştıramazsınız. Yani, URI istediğiniz arama için belirli bir tanımlayıcı değildir.

"Arama" den "create" (farklı) arasında ayrım yapmak için. REST uygulamasına uygun birkaç seçenek vardır:

  • URI'da koleksiyon yerine, iş yerine iş arama gibi bir şey ekleyerek yapabilirsiniz. Bu sadece arama koleksiyonunu ayrı bir kaynak olarak kabul ettiğiniz anlamına gelir.

  • POST'un semantiği hem son işlem OR hem de işlem olduğundan, arama gövdelerini yük ile tanımlayabilirsiniz. {Job: ...} vs. {search: ...} gibi. Uygun bir şekilde göndermek veya işlemek POST mantığına kalmıştır.

Bu hemen hemen bir tasarım / uygulama tercihi. Açık bir kongre olduğunu sanmıyorum.

Yani, daha önce belirlediğiniz gibi, fikir için bir toplama kaynağı tanımlamaktır. jobs

site / işler

Aramayı daraltmak için GET + query params ile arayın. Uzun veya yapılandırılmış veri sorguları bir POST'un gövdesine gider (muhtemelen ayrı bir arama koleksiyonuna). Koleksiyona eklemek için POST ile oluşturun. Ve PUT ile belirli bir URI'ye güncelleyin.

(URI'lerle yapılan stil konvansiyonu FWIW, tüm küçük harfleri tire ile ayrılmış kelimelerle kullanmak içindir. Ancak bu şekilde yapmanız gerektiği anlamına gelmez.)

(Ayrıca şunu söylemeliyim ki, sorunuzdan bu yolun çok aşağısında olduğunuz belli. Açıkça sıraya sokmak için her şeyi açıkça dile getirdim, ancak sorunuz zaten buradaki anlamsal sorunların çoğuna değiniyordu. Cevap: Sadece biraz kongre ve pratik ile onu kandırıyordum.)


Bu ilginç bir fikir - ayırt etmek için yükü kullanmayı düşünmezdim. Neredeyse biraz el altından görünüyor! Fakat sanırım URI şeması aslında fiiller içermiyor - fiili tanımlayan istek türü. Belki de yük, semantik olarak istek tipine URI'den daha yakındır. Tek endişe şudur - API kullanıcısı için şeffaf mı?
Rob Baillie,

Uygulama açısından (Node ve Express kullanıyoruz), bu routegerçekten işlem seçimini kaldıramadığı anlamına gelebilir . Şuna bir göz atmak zorunda kalırdım ...
Rob Baillie

Aynı bağırsak duygusuna sahibim, bunu URI ile ayırmanın daha temiz göründüğü. Ben ileri geri gidiyorum; bu bir yargılama çağrısı. Bununla birlikte, HTTP semantiği, bedene yerleştirilmesine izin verir. Söylemek isterim ki REST, World Wide Web'den sonra modellenmiştir ve WWW, GET ve POST ile oluşturulmuştur.
Rob

8

Genellikle OData sorguları kullanırım, bunlar GET çağrısı olarak çalışır, ancak döndürülen özellikleri kısıtlamanıza ve filtrelemenize izin verir.

Gibi simgeleri kullanın $select=ve $filter=böylece böyle bir URI ile sonuçlanacaktır:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

Ayrıca kullanarak sayfalama yapabilir $skipve $topve sipariş vermeye.

Daha fazla bilgi için OData.org adresini ziyaret edin . Hangi dili kullandığınızı belirtmediniz, ancak ASP.NET ise, WebApi platformu OData sorgularını destekler - diğerleri için (PHP vb.) Muhtemelen onları veritabanı sorgularına çevirmek için kullanabileceğiniz kütüphaneler vardır.


6
İlginç bir bağlantı ve bakmaya değer, ancak GET isteklerinin sorgu dizesinde 2000'den fazla karakteri desteklemediği ve açıklanan sorgunun bundan çok daha uzun olabileceği tamamen açıklanmış olan sorunu çözüyor mu?
Rob Baillie

@RobBaillie Hala bir sorgu dizesiyle bir GET çağrısı olduğu için sanmıyorum. OData'yı, web veri kaynaklarını sorgulamak için bir standart olduğu ve sorgunun 2000 karakterlik bir sorguya sığamayacak kadar karmaşık olması gereken (eğer varsa) birkaç kez yapabileceği her yerde kullanabileceğinizi öneririm. GET araması yaptığınız son nokta
Trevor Pilley

Yaklaşımınızı "GET araması yaptığınız belirli bir son nokta" olarak açıklayabilir misiniz? Bu son noktanın nasıl görüneceğini nasıl düşünebilirsiniz?
Rob Baillie,

@RobBaillie emin - yine hangi teknolojiyi kullandığınızdan emin değilim, ancak ASP.NET'te OData JobsNearMeAddedInTheLast7Daysiçin çok uzun / karmaşık olan sorguyu kapatacak ya da yalnızca GET çağrılarıyla açığa çıkaran belirli bir denetleyici oluşturabilirim. .
Trevor Pilley

1
Anlıyorum. Bazı bacakları olan başka bir ilginç düşünce, bunun benim durumumda yardımcı olacağından emin olmasam da - birçok faset tipi ve olası faset değerleri ile ilgili yönlü araştırma
Rob Baillie

5

Dikkate alınacak bir yaklaşım, olası sorgu kümesinin bir toplama kaynağı olarak ele alınmasıdır, örn /jobs/filters.

POSTVücutta sorgu parametreleri ile bu kaynağa istekleri ya yeni bir kaynak oluşturmak veya varolan eşdeğer filtreyi belirlemek ve onun kimliğini içeren bir URL döndürür: /jobs/filters/12345.

İd sonra işler için bir istek in kullanılabilir: /jobs?filter=12345. GETFiltre kaynağından sonradan gelen istekler, filtrenin tanımını döndürür.

Bu yaklaşımın, sizi filtre tanımlaması için sorgu parametresi biçiminden kurtarması ve potansiyel olarak karmaşık filtreleri tanımlamanız için daha fazla güç sağlama avantajı vardır. VEYA koşulları, bunun sorgu dizeleriyle gerçekleştirilmesinin zor olduğunu düşündüğüm bir örnektir.

Bu yaklaşımın bir dezavantajı, URL'nin okunabilirliğini yitirmenizdir (bununla birlikte GET, filtre kaynağı için bir istek olsa da tanımı alarak bu azaltıcı olabilir ). Bu nedenle, /jobskaynakta sorgu kaynağının sorgu kaynağının aynı veya bir alt kümesini desteklemek isteyebilirsiniz . Bu kısa sorgular için kullanılabilir. Bu özellik sağlanmışsa, iki filtre türü arasında önbelleğe alınabilme özelliğini korumak için, kaynakta sorgu parametreleri kullanılırken /jobs, uygulama dahili olarak bir filtre kaynağı oluşturmalı / yeniden kullanmalı ve URL'yi gösteren bir 302veya 303durumu döndürmelidir /jobs?filter=12345.


Buna ilk tepkim, iyi bir bilgi olmasına rağmen, @burninggramma tarafından sağlanan cevabın gerçekten bir varyasyonudur. Temel olarak "filtre / arama, oluşturma çağrısı ve daha sonra geri çağırma adında yeni bir varlık yarat" şeklindedir. Varyasyon, onu almak için yapılan aramanın bir koleksiyona uygulamak için yapılan bir arama gibidir. İlginç. Ancak hem sizin hem de burninggramma'nın cevabı aynı problemden muzdariptir - filtreleri oluşturma arzum yok. Çok sayıda insan olacak ve RESTful bir uygulamada bulunmak için haricinde depolanmaları gerekmiyor.
Rob Baillie

2
Açıkçası, sorgu parametreleri en iyi çözümdür, ancak sorunuz özellikle bazı sunucular tarafından uygulanan URL sınırından daha uzun olan filtre tanımlarıyla nasıl başa çıkacağınızı sorar. Uzunluk sınırını aşmak için ya bir şekilde sorgu dizesini sıkıştırmanız ya da isteğe bağlı uzunlukta bir beden belirtmeyi destekleyen bir istek yöntemi kullanmanız gerekecektir. Filtreleri bir kaynak olarak değerlendirmek istemiyorsanız, yalnızca filtre tanımlarının POST olduğu dinlendirici olmayan bir arabirimi destekleyin. Önbelleğe alınabilirliği kaybedeceksiniz, ancak verileriniz yeterince değişkense, önbelleğe almanın bir faydası olmaz.
pgraham

Filtreleri saklama gereksinimini basitçe ... depolayarak değil üstesinden gelebilirsiniz. REST ile ilgili hiçbir şey ısrarcı olduğunu garanti etmez. GET /jobs/37Bir sonuç için bir istek yapabilir ve bir sonuç alabilirsiniz, ardından birisi kaynağı siler ve 2 saniye sonra aynı istek bir 404 döndürür. Benzer şekilde, siz POST /searchesve siz bir arama sonucuna yönlendirilirseniz (arama oluşturulur ve 201 Konum başlığı kaynağa), 2 saniye sonra bu sonuç bellekten silinebilir ve yenilenmesi gerekebilir. Uzun süreli depolamaya gerek yoktur.
stevendesu

5

Bu eski bir cevap ama yine de tartışmaya biraz katkıda bulunabiliyorum. Çok sık REST, RESTful ve Mimarinin yanlış anlaşıldığını gözlemledim. RESTful hiç arama yapmayla ilgili hiçbir şeyden bahsetmiyor, RESTful'da mimari hakkında hiçbir şey yok, bir tasarım ilkeleri veya kriterleri var.

Bir Araştırmayı daha iyi tanımlamak için, özellikle bir mimariden bahsetmek zorundayız ve daha iyi uyan bir Kaynak Kaynaklı Mimari (ROA).

RESTful'da tasarım prensipleri var, idempotent bazı cevaplarda okuduğum gibi sonucun değişemeyeceği anlamına gelmiyor, bağımsız bir isteğin sonucu kaç kez yapıldığına bağlı değil. Değişebilir, bir RESTful Api tarafından sunulan bazı verilerle beslenen bir veritabanını sürekli olarak güncellediğimi hayal edelim, aynı GET'in yürütülmesi sonucu değiştirebilir, ancak kaç kez çalıştırıldığına bağlı değildir. Dünyayı dondurmayı başarabilirsem, farklı bir sonuca neden olan kaynağı talep ettiğimde hizmet, devlet, dönüşüm, hiçbir şey olmadığı anlamına gelir.

Tanım olarak, bir kaynak kendi başına bir şey olarak atıfta bulunulması gereken önemli bir şeydir.

Kaynak odaklı bir mimaride (bundan böyle kısalık için ROA olarak adlandıralım), pek çok şey olabilecek kaynağa odaklanırız:

  • Belgenin bir sürümü
  • Belgenin en son güncellenmiş sürümü
  • Bir aramadan gelen bir sonuç
  • Nesnelerin listesi
  • Bir e-ticaretten ilk aldığım makale

Kaynak açısından onu benzersiz kılan şey, sadece bir URI'ye sahip olduğu anlamına gelir.

Bu şekilde, ROA düşünülerek arama RESTful'a mükemmel bir şekilde uyar . GET'i kullanmalıyız çünkü aramanızın normal bir arama olduğunu ve hiçbir şeyi değiştirmeyeceğini varsayıyorum, bu nedenle önemsizdir (eklenen yeni öğelere bağlı olarak farklı şeyler döndürse bile). Burada bu şekilde bir karışıklık var çünkü ROA'ya değil RESTful'a sadık kalabiliyorum, bu da bir arama yaratan ve aynı parametrelerle farklı şeyler döndüren bir kalıp izleyebileceğim anlamına geliyor çünkü ROA'nın adreslenebilirlik ilkesini kullanmıyorum. Bu nasıl? Peki, arama filtrelerini gövdeye veya başlığa gönderirseniz, kaynak ADRESEL DEĞİLDİR.

W3 orijinal belgesinde tam olarak neyin ve URI'nın prensiplerini bulabilirsiniz:

https://www.w3.org/DesignIssues/Axioms

Bu mimarideki herhangi bir URL kendini tanımlamalı olmalıdır. URI'deki her şeyi ele almak için prensipleri izlerseniz, ihtiyaç duyduğunuz veya parametreleri sorgulamak için / (eğik çizgi) kullanabilirsiniz. Bunun sınırlamaları olduğunu biliyoruz, ancak bu mimari kalıp.

RESTful'daki ROA şablonunu takiben, bir arama diğer herhangi bir kaynaktan daha fazla değildir, tek fark, kaynakların nesnenin kendisiyle doğrudan bir ilişki kurmak yerine bir hesaplamadan gelmesidir. İlkeye dayanarak, aşağıdaki modeli temel alan basit bir aritmetik hesaplama hizmetini ele alabilir ve elde edebilirim:

http://myapi.com/sum/1/2

Toplam, 1 ve 2'nin değiştirilebildiği ancak hesaplamanın sonucunun benzersiz olduğu ve adreslenebildiği yerlerde, aynı parametrelerle her aradığımda aynı şeyi elde ederim ve hizmette hiçbir şey değişmiyor. / 1/2 ve / substract / 5/4 resouce ilkelerine mükemmel şekilde uyuyor.


3

GET tamam, her zaman bir URI için aynı sonuçları (gösterimi) döndüren statik bir koleksiyonunuz varsa. Bu aynı zamanda, bu gösterimleri üreten verilerin hiçbir zaman değiştirilmediği anlamına gelir. Kaynak, salt okunur bir veritabanıdır.

Bir ve aynı URI için GET'in farklı sonuçlar döndürmesi , bağımsızlık / güvenlik ve CoolURI ilkesini ihlal eder ve sonuç olarak RESTful değildir . Kararsız fiillerin bir veritabanına yazılması mümkündür, ancak temsili hiçbir zaman etkilememelidirler.

Yaygın bir arama, sonucu referans olarak veren bir POST isteğiyle başlar. Sonucu oluşturur (yenidir ve daha sonraki GET ile alınabilir). Bu sonuç elbette hiyerarşik olabilir (elbette GET edebileceğiniz URI'lere referanslar olabilir) ve uygulama için anlamlı olursa, önceki aramaların öğelerini yeniden kullanabilir.

Bu arada, insanların bunu farklı yaptığını biliyorum. Bana REST’i ihlal etmenin ne kadar kolay olduğunu açıklamana gerek yok.


Aaaaaaaah - bu nasıl çalışması gerekiyor? Teşekkürler!
Rob Baillie

1
Yanlışlık, her zaman tam olarak aynı şekilde geri dönmesi gerektiği anlamına gelmez, HİÇBİR ŞEY değişmezse, aynı şeyi döndürmesi gerektiği anlamına gelmez. Arama bir hesaplamanın sonucu olarak kabul edilebilir ve bu bir kaynağın kendisidir.
Maximiliano Rios,

Hayal kırıklığı aslında, sonucun aynı kaldığı anlamına gelir. Önbellek kontrolünü kullanmak mümkündür ve uygulanabilir. Ve tabii ki daha sonra GET'leri engelleyen DELETE kullanabilirsiniz. Bununla birlikte, bir aracın iç işleyişi hakkında bilgiyi tutması gerekiyorsa, artık RESTful değildir. Yukarıda, REST'in en aşırı fikrinden bahsediyordum. Uygulamada insanlar bunun birçok yönünü ihlal edebilir. Artık önbelleklerin verimli bir şekilde önbelleğe alınmadığı durumlarda fiyatı ödüyorlar.
Martin Sugioarto

“Düşüncesizlik aslında DOES sonucun aynı kaldığı anlamına geliyor.” ... talepten sonra. Mesele şu ki, bu talebin verileri değiştirmemesi.
AndreiMotinga
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.