Bu REST API Gerçekten RPC mi? Roy Fielding öyle düşünüyor gibi görünüyor


100

REST hakkında bildiğimi sandığım şeylerin büyük bir kısmı görünüşe göre yanlış - ve yalnız değilim. Bu soru uzun bir girişe sahip, ancak bilgi biraz dağınık olduğu için gerekli görünüyor. Bu konuya zaten aşina iseniz asıl soru sonunda gelir.

Roy Fielding'in REST API'lerinin hiper metne dayalı olması gerektiğinin ilk paragrafından itibaren, çalışmasının büyük ölçüde yanlış yorumlandığına inandığı oldukça açık:

Herhangi bir HTTP tabanlı arayüzü REST API olarak adlandıran insan sayısı beni hayal kırıklığına uğratıyor. Bugünün örneği SocialSite REST API'sidir . Bu RPC'dir. RPC diye haykırıyor. Ekranda o kadar çok bağlantı var ki ona bir X derecesi verilmesi gerekiyor.

Fielding, bir REST API'nin birkaç özelliğini listelemeye devam ediyor. Bazıları, SO ve diğer forumlarda hem genel uygulamaya hem de genel tavsiyelere aykırı görünüyor. Örneğin:

  • Bir REST API, ilk URI (yer imi) ve hedeflenen kitle için uygun olan (yani API'yi kullanabilecek herhangi bir istemci tarafından anlaşılması beklenen) standartlaştırılmış ortam türleri kümesinin ötesinde hiçbir ön bilgi olmadan girilmelidir. ...

  • Bir REST API, sabit kaynak adlarını veya hiyerarşileri tanımlamamalıdır (istemci ve sunucunun açık bir bağlantısı). ...

  • Bir REST API, tanımlayıcı çabasının neredeyse tamamını kaynakları temsil etmek ve uygulama durumunu yönlendirmek için kullanılan ortam türlerini tanımlamaya veya mevcut standart ortam türleri için genişletilmiş ilişki adlarını ve / veya hiper metin etkin biçimlendirmeyi tanımlamaya harcamalıdır. ...

"Köprü metni" fikri, URI yapısından veya HTTP fiillerinin ne anlama geldiğinden çok daha fazla merkezi bir rol oynar. "Köprü metni" yorumlardan birinde tanımlanmıştır:

Ben [Fielding] hiper metin dediğimde, bilginin ve kontrollerin eşzamanlı sunumunu kastediyorum, öyle ki bilginin kullanıcının (veya otomatın) seçimler elde etmesi ve eylemleri seçmesi için bir yeterlilik haline gelmesi. Hypermedia, bir medya akışına geçici bağlantıların dahil edilmesinin metnin ne anlama geldiğine ilişkin bir genişletmedir; çoğu araştırmacı bu farkı bıraktı.

Köprü metninin bir tarayıcıda HTML olması gerekmez. Makineler, veri biçimini ve ilişki türlerini anladıklarında bağlantıları izleyebilir.

Bu noktada tahmin ediyorum, ancak yukarıdaki ilk iki nokta, aşağıdakine benzeyen bir Foo kaynağı için API belgelerinin, istemci ve sunucu arasında sıkı bir bağlantıya yol açtığını ve bir RESTful sistemde yeri olmadığını gösteriyor.

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

Bunun yerine, bir temsilci, örneğin / foos'a karşı bir GET isteği göndererek tüm Foo'lar için URI'leri keşfetmeye zorlanmalıdır. (Bu URI'lerin yukarıdaki modeli izlediği ortaya çıkabilir, ancak bu noktanın dışındadır.) Yanıt, her bir öğeye nasıl erişileceğini ve bununla neler yapılabileceğini iletebilen bir ortam türü kullanır ve yukarıdaki üçüncü noktaya yol açar . Bu nedenle, API dokümantasyonu, yanıtta bulunan hipermetin nasıl yorumlanacağını açıklamaya odaklanmalıdır.

Ayrıca, bir Foo kaynağına bir URI talep edildiğinde, yanıt, bir aracının, örneğin URI'leri aracılığıyla ilişkili ve ana kaynaklara erişerek veya oluşturulduktan sonra harekete geçerek nasıl ilerleyeceğini keşfetmesi için gereken tüm bilgileri içerir / bir kaynağın silinmesi.

Tüm sistemin anahtarı, yanıtın, kendisi devam etmek için aracıya seçenekleri ileten bir medya türünde bulunan hiper metinden oluşmasıdır. Bir tarayıcının insanlar için çalışma şeklinden farklı değildir.

Ama bu, şu andaki en iyi tahminim.

Fielding , tartışmasının çok soyut, örneklerden yoksun ve jargon açısından zengin olduğu yönündeki eleştirilere yanıt verdiği bir takip yayınladı :

Diğerleri, yazdıklarımı bugünün bazı pratik endişelerine daha doğrudan veya uygulanabilir yollarla deşifre etmeye çalışacaklar. Muhtemelen yapmayacağım, çünkü bir sonraki konuyla boğuşmakla, bir konferansa hazırlanmakla, başka bir standart yazmakla, uzak bir yere seyahat etmekle ya da maaş çekimi kazandığımı hissetmeme izin veren küçük şeyler yapmakla çok meşgulüm.

Öyleyse, pratik bir zihniyete sahip olan REST uzmanları için iki basit soru: Fielding'in söylediklerini nasıl yorumluyorsunuz ve REST API'lerini belgelerken / uygularken bunu nasıl uygulamaya koyuyorsunuz?

Düzenleme: Bu soru, bahsettiğiniz şey için bir adınız yoksa bir şeyi öğrenmenin ne kadar zor olabileceğinin bir örneğidir. Bu durumda adı "Uygulama Durumu Motoru Olarak Hiper Ortam" (HATEOAS) adıdır.


26
John, Rich sadece sahip olduğu zihniyet değişikliğini açıklıyor. Bunda öznel veya tartışmacı hiçbir şey yok. Açık tutmak için oy verin - SO'da gördüğüm 'dinlenme' etiketli daha iyi sorulardan biri.
Keith Gaughan

4
Keith, "zihniyetteki değişikliği açıklamak", SO'da değil, blogunda yapması gereken bir şey.
John Saunders

13
Zihniyetindeki değişimini açıklamıyor, anlayışının doğru olup olmadığını soruyor.
aehlke

4
Mükemmel özet. Bu sorudan çoğu cevaptan daha fazlasını öğrendim.
Martin Konecny

Yanıtlar:


21

Bence açıklamanız çoğunlukla bunu kapsıyor. URI'ler, çoğunlukla, uygulamaya erişmek için kullanıcı aracısı tarafından kullanılan yer imi URI'sının ötesinde iletilmemesi gereken opak tanımlayıcılardır.

Belgeleme gelince, bu soru birkaç kez yapıldı. Ortam türünüzü, içerdiği köprü kontrolleriyle (bağlantılar ve formlar) ve isterseniz etkileşim modeliyle birlikte belgelersiniz (bkz. AtomPub).

URI'leri veya onları nasıl oluşturacağınızı belgelerseniz, yanlış yapıyorsunuz demektir.


Bu hala doğru mu? Bu URI'leri kasıtlı olarak yanıtın bir parçası olarak yapan Ionspec gibi API yanıtı özellikleri vardır.
Sean Pianka

Evet, sahipler. Bu noktada, bu belgelenmiş URI'lerin, kalması garanti edilen (bunlardan birkaçı nadir ve oldukça kullanışlı olmayan) uygulamaya giriş noktaları olup olmadığını veya insanlar kod üretimi istedikleri için bunların gömülü olup olmadığını anlamakla ilgili bir soru. doğrudan kodun içine girerek sunucunun müşteriye işleri nasıl yapabileceğini bildirmesini engelleyen bir özellik. Müşteri bu sözleşmeden dolayı bildiğini düşünürse, hiper medyada değilsiniz, 18 yıl önce karşılaştığınız sorunların aynısıyla, günümüzün modern openapi sabun modeline girersiniz.
SerialSeb

Doğru olan, birçok API dokümantasyon dilinin son 11 yılda ortaya çıktığı, ancak temellerin değişmediğidir. Bu bağlantıları keşfetmenin veya en azından URI şablon keşfinin değerinin, bunları dinamik olarak kullanabilen yeniden kullanılabilir genel istemci kodu oluşturmak olduğuna inanıyorum ve sunucu tarafındaki birçok uygulamanın aynı istemci kodunu yeniden kullanmasına izin veriyor. URI yerleştirme, bu tür senaryoları zorlaştırmaya devam eder, ancak bu biçimleri kullanırsanız, oluşturulan bir istemciyi bu özelliklerden sıkıca bağlama eğiliminde olursunuz, bu nedenle bu özelliği zaten kaybettiniz.
Seri Şubat

"Müşteri bu sözleşmeden dolayı bildiğini düşünürse, hiper medyada değilsiniz, 18 yıl önce karşılaştığınız sorunların aynısıyla, günümüzün modern openapi sabun modeline girersiniz." Bununla ne demek istediğini açıklayabilir misin?
Sean Pianka'ya

8

Yorumunuz bana doğru görünüyor. Fielding'in kısıtlamalarının pratik olarak uygulanabileceğine inanıyorum.

Birinin bir REST arayüzünün nasıl belgeleneceğine dair bazı iyi örnekler yayınladığını görmek isterim. Çok fazla kötü örnek var, kullanıcıları işaret edecek bazı geçerli örnekler çok değerli olacaktır.


2
Vay. O Kaynak Modeli sayfası gözlerimi yaşarttı. Umarım bu bir trend başlatır.
Darrel Miller

Bu utanç verici bir durumdur, bu temelde web'deki böyle bir API'nin tek örneği! Daha da kötüsü, ilkeyi izleyen (bulduğum) hiçbir iyi istemci kodu örneği yok.
jkp

1
@DarrelMiller Ama bu Medya Türleri çok "spesifik" değil mi? Bana öyle geliyor ki, API'leri gerçekten sadece bir MIME kullanıyor: application/jsonve Kaynak Modeli gerçekten ilişkiler. REST'in bu yönünü yanlış mı anladım? Ayrıca , bu "tek nitelikli" sözleşmelerden kaçınılması gerektiğine işaret eden görünen SO cevaplarınızdan birini okudum ...
edsioufi

2
@RichApodaca Bağlantınız dizanteri yüzünden öldü. web.archive.org/web/20170409132237/https://kenai.com/projects/…
forresthopkinsa

5

HATEOAS'ı takiben yazılmış bir API'nin iyi bir örneğini arıyordum ve birini bulmakta güçlük çekiyorum (SunCloud API ve AtomPub öğelerinin "normal" bir API durumuna uygulanmasının zor olduğunu gördüm). Bu yüzden, Roy Fieldings'in uygun bir REST uygulaması olmanın ne anlama geldiğine dair tavsiyesini takip eden blogumda gerçekçi bir örnek oluşturmaya çalıştım. Prensipte oldukça basit olmasına rağmen (bir web sayfası yerine bir API ile çalışırken sadece kafa karıştırıcı) bir örnek ortaya koymayı çok zor buldum. Roy'un neyle ilgili olduğunu anlıyorum ve kabul ediyorum, bir API için düzgün bir şekilde uygulamak sadece bir zihniyet değişikliği.

Bir göz atın: Rest kullanarak API Örneği


4

URI'lerin nasıl oluşturulacağına ilişkin talimat vermenin bir istisnası, köprü metindeki diğer alanları kullanarak istemci tarafından otomatik olarak değiştirilecek alanlarla, köprü metni yanıtında bir URI şablonu göndermeye izin verilebilir olmasıdır. Bu genellikle çok fazla bant genişliği tasarrufu sağlamaz, çünkü gzip sıkıştırması URI'lerin tekrarlanan kısımlarını bununla uğraşmayacak kadar iyi işleyecektir.

REST ve ilgili HATEOAS hakkında bazı güzel tartışmalar:

RESTFul API'lerinde HATEOAS Kullanmanın (Ayrıca) Avantajları

Bir fincan kahve nasıl alınır



4

Çoğu insanın yanlış anladığı şey, (en azından sanırım) REST dünyasında "Dinlenme arayüzünüzü" belgelememenizdir, belgelediğiniz şey, sunucunuzdan veya hizmetinizden bağımsız olarak bir ortam türüdür.


2

Sanırım REST'in şu anda orada bulunduğu yılların sayısı boyunca, teknoloji uzmanları bir Kaynak kavramı ve gerçekte neyin RESTful olup olmadığı ile uzlaşmaya başladılar.

Richardson Olgunluk Modeline göre, API'nizin ne kadar RESTful olduğunu tanımlayan 4 seviye (0-3) vardır; 3, tıpkı Roy Fielding'in amaçladığı gibi, gerçekten RESTful API anlamına gelir.

Düzey 0, SABUN gibi bir giriş noktası URI'ye sahip olduğunuz zamandır.

Seviye 1, API'nin farklı kaynaklar arasında ayrım yapabildiği ve birden fazla giriş noktasına sahip olduğu anlamına gelir - hala SABUN kokuyor.

Seviye 2, HTTP fiillerini kullandığınız zamandır - öncelikle GET, POST, DELETE. Bu, REST'in gerçekten ortaya çıktığı seviyedir.

Seviye 3'te, API'nizi gerçekten RESTful yapmak için hiper medya kontrollerini kullanmaya başlarsınız .

Daha fazla okumak için önerilen bağlantılar:


1

Kesinlikle doğru. Ek olarak, URI şablonlarının, desenler sunucudan alınan belgelerden olduğu sürece bir RESTful uygulamasında mükemmel derecede iyi olduğunu not ederim (OpenSearch uygun bir örnektir). URI şablonları için, nerede kullanıldıklarını ve şablondaki beklenen yer tutucuların ne olduğunu belgelersiniz, ancak şablonların kendilerini belgelemezsiniz. Wahnfrieden'in söylediğinin biraz aksine, bu bir istisna değil.

Örneğin, çalışmamda dahili bir etki alanı yönetim sistemimiz var ve hizmet belgesi iki URI şablonunu belirtiyor: biri bir etki alanı kaynağı için en iyi tahmin URI'sı oluşturmak için, diğeri etki alanı kullanılabilirliğini sorgulamak için bir URI oluşturmak için. Belirli bir alan adının URI'sinin ne olduğunu bulmak için alan koleksiyonunu incelemek hala mümkündür, ancak yönettiği çok sayıda alan adı göz önüne alındığında, bu müşteri için mümkün olmayacaktır, bu nedenle onlara ne olduğunu tahmin etmeleri için bir yol verin. Bir alan kaynağının URI'si, istemcinin bakış açısından uygulama kolaylığı ve sunucunun bant genişliği açısından büyük bir kazanç olabilir.

Sorunuza gelince: Normatif dokümantasyonumuz, açık kaynaklar, çeşitli yöntemlerin bu kaynaklar üzerindeki etkisi, kullanılan temsil ortamı türleri ve şemaları ve bu temsillerdeki URI'lerin ne tür kaynaklara işaret ettiği ile ilgilidir.

Ayrıca, belgede bahsedilen URI'ları çok fazla okumamak için bir sorumluluk reddi beyanı ekleyen ve tipik istemci-sunucu etkileşimlerine örnekler veren normatif olmayan (bilgilendirici) belgeleri de dahil ediyoruz. Bu, oldukça soyut normatif dokümantasyonu somut terimlerle ifade eder.


1
Bant dışı API'nizin bir parçası olarak URI şablonları sağlamakta bir sorun yoktur. Sadece LÜTFEN buna REST demeyin, çünkü öyle değil. Bu çok büyük miktarda birleştirme ve tam olarak REST'in kaçınmak için yapıldığı şey. Ama sizin de dediğiniz gibi, REST her uygulama için değildir. Bu yüzden her uygulamanın REST olduğunu düşünmeyin.
aehlke

1
Aslında katılıyorum. Sanırım ben öyle söyledim. Ancak, bant dışı URI şablonları sağlamak için gerçekten iyi bir neden göremiyorum.
Keith Gaughan

0

GET /foos/createFormYaratmaya gittiğimizde sağlanması gereken form alanları değerlerini almak için çağrıldığını varsayalım POST /foos. Şimdi bu belirli URL, yani foos oluşturmak için kullanılan 1 GET /foos/createForm, Fielding'in önerisine göre bir eylem gönderme bağlantısı olarak yanıt içinde belirtilmelidir , değil mi?
O zaman eylemleri iyi bilinen Http fiillerine eylemlere eşlemenin faydası nedir, "kod / yapılandırma üzerinden kural" olayı geçersiz kılınmıştır.

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.