Kaynak üzerinde sunucu tarafı yöntemini RESTful bir şekilde çağırma


142

Unutmayın, REST hakkında temel bir anlayışım var. Diyelim ki bu URL'ye sahibim:

http://api.animals.com/v1/dogs/1/

Ve şimdi, sunucuyu köpek havlaması yapmak istiyorum. Bunun nasıl yapılacağını yalnızca sunucu bilir. Diyelim ki, sonsuzluğun geri kalanı için köpek kabuğunu her 10 dakikada bir yapan bir CRON işi yapmak istiyorum. Bu çağrı neye benziyor? Bunu yapmak istiyorum:

URL isteği:

ACTION http://api.animals.com/v1/dogs/1/

İstek gövdesinde:

{"action":"bark"}

Kendi HTTP yöntemimi oluşturduğum için bana kızmadan önce, bana yardımcı ol ve bana RESTful şekilde bir sunucu tarafı yöntemini nasıl çağırmam gerektiğine dair daha iyi bir fikir ver. :)

AÇIKLAMAYI DÜZENLEME

"Kabuk" yönteminin ne yaptığı hakkında daha fazla açıklama. Farklı yapılandırılmış API çağrılarıyla sonuçlanabilecek bazı seçenekler şunlardır:

  1. bark sadece dog.email adresine bir e-posta gönderir ve hiçbir şey kaydetmez.
  2. bark dog.email'e ve dog.barkCount artışlarına 1 e-posta gönderir.
  3. kabuk kabuğu ortaya çıktığında bark.timestamp kaydı ile yeni bir "kabuk" kaydı oluşturur. Ayrıca dog.barkCount değerini 1 arttırır.
  4. bark, Github'dan köpek kodunun en son sürümünü aşağı çekmek için bir sistem komutu çalıştırır. Daha sonra dog.owner'a yeni köpek kodunun üretimde olduğunu bildiren bir metin mesajı gönderir.

14
İlginç bir şekilde, bir ödül eklemek, ilk aldığınızdan daha kötü yanıtlar çekmiş gibi görünüyor ;-) Yanıtları değerlendirirken şunu unutmayın: 1) HTTP fiillerine ilişkin spesifikasyonlar POST dışında herhangi bir seçimi engeller. 2) REST'in URL yapısı ile ilgisi yoktur - yararları (ölçeklenebilirlik, güvenilirlik, görünürlük vb.) Sağlamaktan ziyade jenerik bir çelişkiler listesidir (vatansız, önbelleğe alınabilir, katmanlı, tek biçimli arayüz, vb.). 3) Mevcut uygulama (RPC spesifikasyonlarında POST kullanmak gibi) kendi API kurallarını oluşturan tanımlayıcıları ortadan kaldırır. 4) REST, tekdüze bir arayüz gerektirir (HTTP spesifikasyonunu izleyerek).
Raymond Hettinger

@Kirk yeni cevaplar hakkındaki düşüncelerin neler? Hâlâ bilmek istediğiniz ancak hiçbirinde ele alınmayan bir şey var mı? Daha yararlı olabilirse cevabımı tekrar düzenlemekten mutluluk duyacağım.
Ürdün

@RaymondHettinger PATCHuygun olabilir. Cevabımın neden doğru olduğunu açıklıyorum .
Ürdün

PATCH yalnızca dog.barkCount değerini bir arttırmak için uygun olacaktır . POST, e-posta gönderme, yeni bir kabuk kaydı oluşturma, Github'dan indirmek için komutları çalıştırma veya bir metin mesajını tetikleme yöntemidir. @Jordan, PATCH RFC'yi okumanız yaratıcıdır, ancak kısmi kaynak değişikliği için PUT'un bir varyantı olarak niyeti ile biraz çelişmektedir. Uzak yordam çağrıları için POST kullanma standart uygulamasını kabul etmek yerine, HTTP özelliklerinin alışılmadık okumaları ile OP'ye yardımcı olduğunuzu düşünmüyorum.
Raymond Hettinger

@RaymondHettinger uygulaması fiili POST'u standartlaştırıyor mu? Gördüğüm tüm standart RPC arabirimleri, URI'ye karşı varlığa (RESTful değil) göre bir kaynak tanımlar, bu nedenle RPC kuralını önceliklendiren geçerli bir yanıtın geleneksel olmayan olması gerekir, ki bu da geleneksel RPC'nin değerini çürütür: biri yaratıcı veya tutarsız . Veri işleme için her şeyi yakaladıkları için POST ile hiçbir zaman yanlış gidemezsiniz , ancak daha spesifik yöntemler vardır. REST, durum değiştirme prosedürlerini adlandırmak yerine kaynakları adlandırmak ve durumlarındaki değişiklikleri tanımlamak anlamına gelir. PATCH ve POST durum değişikliklerini tanımlar.
Ürdün

Yanıtlar:


280

Neden RESTful tasarımı hedefliyoruz?

RESTful ilkeleri , web sitelerini kolaylaştıran özellikleri ( rastgele bir insan kullanıcının "sörf" yapması ) web hizmetleri API tasarımına getirir , böylece bir programcının kullanımı kolaydır. REST iyi değil çünkü REST, iyi çünkü iyi. Ve çoğunlukla iyidir çünkü basittir .

Bazılarının "özellik eksikliği" olarak adlandırdığı düz HTTP'nin (SOAP zarfları ve tek URI'ye aşırı yüklenmiş POSThizmetler olmadan) basitliği aslında en büyük gücüdür . Hemen, HTTP adreslenebilirlik ve vatansızlığa sahip olmanızı ister : HTTP'yi günümüzün mega sitelerine (ve mega hizmetlerine) ölçeklendiren iki temel tasarım kararı.

Ancak REST gümüş bir bullet değildir: Bazen bir RPC tarzı ("Uzak Yordam Çağrısı" - SOAP gibi) uygun olabilir ve bazen diğer ihtiyaçlar Web'in erdemlerinden önceliklidir. Bu iyi. Gerçekten sevmediğimiz şey gereksiz karmaşıklıktır . Çoğu zaman bir programcı veya şirket, düz eski HTTP'nin iyi işleyebileceği bir iş için RPC tarzı Hizmetler getirir. Etkisi, HTTP'nin "gerçekten" ne olduğunu açıklayan muazzam bir XML yükü için bir taşıma protokolüne indirgenmiş olmasıdır (URI veya HTTP yöntemi bu konuda bir ipucu vermez). Ortaya çıkan hizmet çok karmaşıktır, hata ayıklamak imkansızdır ve istemcileriniz geliştiricinin istediği şekilde tam olarak kurulmadıkça çalışmaz .

Java / C # kodu olabilir aynı şekilde değil sadece bir tasarım RESTful yapmaz HTTP kullanarak, nesne yönelimli. Birisi , eylemleri ve çağrılması gereken uzak yöntemler açısından hizmetleri hakkında düşünme acele yakalanabilir . Bunun çoğunlukla bir RPC-Stil hizmetine (veya bir REST-RPC-melezine) neden olacağına şaşmamalı. İlk adım farklı düşünmektir. RESTful tasarımı birçok yönden elde edilebilir, bunun bir yolu uygulamanızı eylemler yerine kaynaklar açısından düşünmektir:

💡 Gerçekleştirebileceği eylemler açısından düşünmek yerine ("haritada yerler için arama yapın") ...

... bu işlemlerin sonuçları açısından düşünmeye çalışın ("haritadaki bir arama ölçütleriyle eşleşen yerlerin listesi").

Aşağıdaki örneklere bakacağım. (REST'in diğer önemli yönü HATEOAS kullanımıdır - Burada fırçalamıyorum, ancak başka bir gönderide hızlı bir şekilde konuşuyorum .)


İlk tasarımın sorunları

Önerilen tasarıma bir göz atalım:

ACTION http://api.animals.com/v1/dogs/1/

Öncelikle, yeni bir HTTP fiili ( ACTION) oluşturmayı düşünmemeliyiz . Genel olarak konuşursak, bu birkaç nedenden dolayı istenmeyen bir durumdur :

  • (1) Yalnızca hizmet URI'sı verildiğinde, "rastgele" bir programcı ACTIONfiilin var olduğunu nasıl bilecek ?
  • (2) programcı var olduğunu biliyorsa, anlambilimini nasıl bilecek? Bu fiil ne anlama geliyor?
  • (3) fiilin sahip olması gereken özellikler (güvenlik, idempotence) ne olmalıdır?
  • (4) programcının yalnızca standart HTTP fiillerini işleyen çok basit bir istemcisi varsa ne olur?
  • (5) ...

Şimdi let kullanmayı düşününPOST (aşağıda, sadece şimdi bunun için benim sözüme niye ele alacağız):

POST /v1/dogs/1/ HTTP/1.1
Host: api.animals.com

{"action":"bark"}

Bu iyi olabilir ... ama sadece :

  • {"action":"bark"}bir belgedir; ve
  • /v1/dogs/1/"belge işlemcisi" (fabrika benzeri) bir URI idi. "Belge işlemcisi", yalnızca "şeyleri" atacağınız ve onlar hakkında "unutacağınız" bir URI'dir - işlemci, "fırlatma" işleminden sonra sizi yeni oluşturulan bir kaynağa yönlendirebilir. Örneğin, mesaj gönderildikten sonra sizi mesajın işlenmesinin durumunu gösteren bir URI'ye yönlendirecek olan bir Message Broker hizmetine mesaj göndermek için URI.

Sisteminiz hakkında fazla bir şey bilmiyorum, ama her ikisinin de doğru olmadığına bahse girerim:

  • {"action":"bark"} bir belge değil , aslında hizmete ninja gizlice girmeye çalıştığınız yöntemdir ; ve
  • /v1/dogs/1/URI "köpek" kaynak (muhtemelen köpek temsil id==1) ve bir belge işlemci.

Şimdi bildiğimiz tek şey yukarıdaki tasarımın o kadar RESTful olmadığı, ama tam olarak nedir? Bunda bu kadar kötü olan ne? Temel olarak, kötü çünkü karmaşık anlamları olan karmaşık URI. Ondan bir şey çıkaramazsınız. Bir programcı, bir köpeğin içine barkgizlice aşılan bir eylemi olduğunu nasıl bilecektir POST?


Sorunuzun API çağrılarını tasarlama

Öyleyse kovalamaca başlayalım ve kaynak açısından düşünerek bu kabukları DİNLENECEK şekilde tasarlamaya çalışalım . Restful Web Services kitabını alıntılamama izin ver :

Bir POSTistek varolan birinden yeni kaynak oluşturmak için bir girişimdir. Varolan kaynak, bir veri yapısı anlamında yenisinin üst öğesi olabilir, bir ağacın kökünün tüm yaprak düğümlerinin üst öğesi olması. Veya mevcut kaynak , tek amacı başka kaynaklar üretmek olan özel bir "fabrika" kaynağı olabilir . Bir POSTistekle birlikte gönderilen temsil , yeni kaynağın başlangıç ​​durumunu açıklar. PUT ile olduğu gibi, bir POSTisteğin de bir temsili içermesi gerekmez.

Biz görebilirsiniz yukarıdaki açıklamayı takiben barkolarak modellenebilir bir bir subresourcedog (a beri bark, bir kabuk "havlamaya" edilir bir köpek, içinde bulunur tarafından bir köpek).

Bu akıl yürütmeden zaten:

  • Yöntem POST
  • Kaynak, /barksköpeğin alt kaynağı : /v1/dogs/1/barksbir bark"fabrika" yı temsil eder . Bu URI her köpek için benzersizdir (altında olduğu için /v1/dogs/{id}).

Artık listenizdeki her durumun belirli bir davranışı var.

1. havlama sadece bir e-posta gönderir dog.emailve hiçbir şey kaydeder.

Birincisi, havlama (e-posta gönderme) eşzamanlı mı yoksa eşzamansız mı? İkincisi, barkistek herhangi bir belge (e-posta, belki) gerektiriyor mu yoksa boş mu?


1.1 havlama e-posta gönderir dog.emailve hiçbir şey kaydetmez (eşzamanlı görev olarak)

Bu dava basit. barksFabrika kaynağına yapılan bir çağrı hemen bir havlama (gönderilen bir e-posta) verir ve yanıt (tamamsa ya da değilse) hemen verilir:

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

(entity-body is empty - or, if you require a **document**, place it here)

200 OK

Hiçbir şeyi kaydetmediği (değiştirdiği) 200 OKiçin yeterlidir. Her şeyin beklendiği gibi gittiğini gösterir.


1.2 havlama e-posta gönderir dog.emailve hiçbir şey kaydetmez (eşzamansız görev olarak)

Bu durumda, istemcinin barkgörevi izlemek için bir yolu olmalıdır . barkGörev sonra o kendi URI ile bir kaynak olmalıdır .:

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

{document body, if needed;
NOTE: when possible, the response SHOULD contain a short hypertext note with a hyperlink
to the newly created resource (bark) URI, the same returned in the Location header
(also notice that, for the 202 status code, the Location header meaning is not
standardized, thus the importance of a hipertext/hyperlink response)}

202 Accepted
Location: http://api.animals.com/v1/dogs/1/barks/a65h44

Bu şekilde, her barkbiri izlenebilir. Istemci daha sonra geçerli durumunu bilmek GETiçin barkURI için a verebilir . Belki de DELETEiptal etmek için a kullanın.


2. ağaç kabuğu bir e-posta gönderir dog.emailve sonra artar dog.barkCount1

İstemciye dogkaynağın değiştiğini bildirmek istiyorsanız, bu daha zor olabilir :

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

{document body, if needed; when possible, containing a hipertext/hyperlink with the address
in the Location header -- says the standard}

303 See Other
Location: http://api.animals.com/v1/dogs/1

Bu durumda, locationbaşlığın amacı müşteriye bir göz atması gerektiğini bildirmektir dog. Gönderen yaklaşık HTTP RFC303 :

Bu yöntem öncelikle, POSTetkinleştirilmiş bir komut dosyasının çıktısının kullanıcı aracısını seçilen bir kaynağa yönlendirmesine izin vermek için vardır.

Görev eşzamansızsa, durum barkgibi bir alt kaynağa ihtiyaç duyulur ve görev tamamlandığında bir defada döndürülmelidir .1.2303GET .../barks/Y


3. ağaç kabuğu oluştuğunda barkkayıt ile yeni bir " " kaydı oluşturur bark.timestamp. Ayrıca dog.barkCount1 artar .

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

(document body, if needed)

201 Created
Location: http://api.animals.com/v1/dogs/1/barks/a65h44

Burada, barkistek nedeniyle oluşturulan, bu nedenle durum 201 Createduygulanır.

Oluşturma senkronize değilse, bunun yerine 202 Accepted( HTTP RFC'nin dediği gibi ) gereklidir .

Kaydedilen zaman damgası barkkaynağın bir parçasıdır ve bir a ile alınabilir GET. Güncellenen köpek de "belgelenebilir" GET dogs/X/barks/Y.


4. bark, Github'dan köpek kodunun en son sürümünü aşağı çekmek için bir sistem komutu çalıştırır. Daha sonra dog.owner, yeni köpek kodunun üretimde olduğunu bildirmek için bir metin mesajı gönderir .

Bunun ifadesi karmaşıktır, ancak hemen hemen basit bir asenkron görevdir:

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

(document body, if needed)

202 Accepted
Location: http://api.animals.com/v1/dogs/1/barks/a65h44

Müşteri daha sonra geçerli durumu bilmek için GETs /v1/dogs/1/barks/a65h44gönderir (kod çekildiyse, e-posta sahibine gönderilir). Köpek her değiştiğinde, a 303uygulanabilir.


Paketleme

Roy Fielding'den alıntı :

REST'in yöntemlere gereksinim duyduğu tek şey, bunların tüm kaynaklar için eşit olarak tanımlanmasıdır (yani, aracıların, talebin anlamını anlamak için kaynak türünü bilmeleri gerekmez).

Yukarıdaki örneklerde, POSTeşit olarak tasarlanmıştır. Köpeği " bark" yapacak . Bu güvenli değildir (kabuğun kaynaklar üzerinde etkileri vardır) veya fiili iyi barkuyan idempotent (her istek yeni bir sonuç verir ) POST.

Bir programcı bilir: a POST, a barksverir bark. Yanıt durum kodları (gerektiğinde varlık-gövdesi ve başlıklar ile birlikte) neyin değiştiğini ve müşterinin nasıl ilerleyebileceğini ve ilerlemesi gerektiğini açıklamakla görevlidir.

Not: Kullanılan başlıca kaynaklar: " Restful Web Services " kitabı, HTTP RFC ve Roy Fielding'in blogu .




Düzenle:

Soru ve dolayısıyla cevap ilk yaratıldıklarından bu yana biraz değişti. Orijinal soru bir URI gibi tasarımı konusunda sorular:

ACTION http://api.animals.com/v1/dogs/1/?action=bark

Aşağıda neden iyi bir seçim olmadığının açıklaması verilmiştir:

İstemciler sunucu anlatmak nasıl GEREKENLER verilerle olan yöntem bilgisi .

  • RESTful web hizmetleri HTTP yönteminde yöntem bilgilerini iletir.
  • Tipik RPC Stili ve SOAP hizmetleri, varlıklarını gövde gövdesinde ve HTTP üstbilgisinde tutar.

Verilerin HANGİ PARÇASI [istemci sunucunun] üzerinde çalışmasını istemek, kapsam belirleme bilgisidir .

  • RESTful hizmetleri URI kullanır. SOAP / RPC-Style hizmetleri varlık gövdesi ve HTTP üstbilgilerini bir kez daha kullanır.

Örnek olarak Google'ın URI'sını ele alalım http://www.google.com/search?q=DOG. Orada yöntem bilgisi GETve kapsam bilgisi vardır /search?q=DOG.

Uzun lafın kısası:

  • Gelen dinlendirici mimarileri , yöntem bilgisi HTTP yöntemi girer.
  • In Kaynak Odaklı Mimarilerin , kapsam bilgisi URI girer.

Ve temel kural:

HTTP yöntemi yöntem bilgileriyle eşleşmezse, hizmet RESTful değildir. Kapsam belirleme bilgileri URI'de değilse, hizmet kaynak odaklı değildir.

URL'ye (veya varlık gövdesine) "havlama" " işlemini " koyabilir ve kullanabilirsiniz POST. Sorun değil, işe yarıyor ve bunu yapmanın en basit yolu olabilir, ancak bu RESTful değil .

Hizmetinizi gerçekten GERÇEKLEŞTİRMEK için geri adım atmanız ve burada gerçekten ne yapmak istediğinizi düşünmeniz gerekebilir (kaynaklar üzerinde ne gibi etkileri olacaktır).

Özel iş ihtiyaçlarınız hakkında konuşamam, ancak size bir örnek vereyim: Siparişlerin URI'lerde olduğu RESTful bir sipariş servisi düşünün example.com/order/123.

Şimdi bir siparişi iptal etmek istediğimizi söyleyin, bunu nasıl yapacağız? Bir bu olduğunu düşünüyorum için cazip olabilir "iptal" "eylem" ve olarak dizayn POST example.com/order/123?do=cancel.

Yukarıda bahsettiğimiz gibi bu RESTful değil. Bunun yerine, adresine gönderilen bir öğeyle PUTyeni bir temsili olabilir :ordercanceledtrue

PUT /order/123 HTTP/1.1
Content-Type: application/xml

<order id="123">
    <customer id="89987">...</customer>
    <canceled>true</canceled>
    ...
</order>

Ve bu kadar. Sipariş iptal edilemezse, belirli bir durum kodu döndürülebilir. ( POST /order/123/canceledVarlık gövdesinde olduğu gibi bir alt kaynak tasarımı truebasitlik açısından da kullanılabilir.)

Özel senaryoda, benzer bir şey deneyebilirsiniz. Bu şekilde, bir köpek havlarken, örneğin, bir GETat /v1/dogs/1/bu bilgiyi içerebilir (örn. <barking>true</barking>) . Veya ... bu çok karmaşıksa, RESTful gereksiniminizi gevşetin ve sadık kalın POST.

Güncelleme:

Cevabı çok büyük yapmak istemiyorum, ancak bir dizi kaynak olarak bir algoritmayı (bir eylemi ) açığa çıkarmak biraz zaman alıyor . Eylemler açısından düşünmek yerine ( "haritada yerler için arama yapın" ), kişinin bu eylemin sonuçları açısından düşünmesi gerekir ( "harita üzerinde bir arama ölçütleriyle eşleşen yerlerin listesi" ).

Tasarımınızın HTTP'nin tek tip arayüzüne uymadığını fark ederseniz bu adıma geri dönebilirsiniz.

Sorgu değişkenleri olan bilgiyi kapsam , ama yapacak değil (yeni kaynaklar anlamında olabildikleri /post?lang=enaçıkça aynı şekilde kaynak /post?lang=jp, sadece farklı gösterim). Aksine, onlar iletmek için kullanılan istemci durumunu (gibi ?page=10, yani devlet sunucusunda tutulur değildir bu yüzden, ?lang=enburada da bir örnektir) ya da giriş parametreleri için algoritmik kaynakların ( /search?q=dogs, /dogs?code=1). Yine, farklı kaynaklar değil.

HTTP fiillerinin (yöntemler) özellikleri:

?action=somethingURI'de gösterilen başka bir açık nokta RESTful değil, HTTP fiillerinin özellikleridir:

  • GETve HEADgüvenli (ve idempotent);
  • PUTve DELETEsadece idempotenttir;
  • POST Ne de.

Güvenlik : A GETveya HEADistek, herhangi bir sunucu durumunu değiştirme isteği değil, bazı verileri okuma isteğidir. Müşteri bir kez yapabilir GETveya HEAD10 kez talep edebilir ve bir kez yapmak ya da hiç yapmamakla aynıdır .

Idempotence : Bir defada veya birden çok kez uygulansanız da aynı etkiye sahip bir idempotent işlem (matematikte, sıfıra çarpma idempotenttir). Eğer DELETEbir kaynak bir kez, tekrar silmeyi aynı etkiyi (kaynaktır olacak GONEzaten).

POSTne güvenli ne de idempotent. POSTBir 'fabrika' kaynağına iki özdeş istekte bulunmak muhtemelen aynı bilgileri içeren iki alt kaynağa neden olacaktır. Aşırı yüklendiğinde (URI veya varlık gövdesinde yöntem) POST, tüm bahisler kapalıdır.

Her iki özellik de HTTP protokolünün başarısı için önemliydi (güvenilmez ağlar üzerinden!): GETSayfayı tamamen yüklenene kadar beklemeden kaç kez güncellediniz ( )?

Bir eylem oluşturmak ve URL'ye yerleştirmek, HTTP yöntemlerinin sözleşmesini açıkça ihlal eder. Bir kez daha, teknoloji size izin veriyor, bunu yapabilirsiniz, ancak bu RESTful tasarımı değil.


URL'de bir eylem olarak belirlenen bir sunucuda eylem çağırmanın RESTful olmadığı fikriyle çekişiyorum. "veri işleme sürecine bir veri bloğu ... sağlamak"POST için tasarlanmıştır . Pek çok insan kaynakları eylemlerden ayırıyor gibi görünüyor, ama gerçekten eylemler sadece bir tür kaynak.
Jacob Stevens

1
@JacobStevens OP soruyu biraz değiştirdi, bu yüzden cevabımı daha doğrudan yapmak için güncellemeliyim ( orijinal soruyu kontrol edin , belki ne demek istediğimi göreceksiniz). POST"Veri işleme sürecine bir veri bloğu ... sağlama" ile hemfikirim , ancak fark gerçekten bir veri bloğunun değil, bir veri bloğunun ve prosedürün (eylem, yöntem, komut) sonra idam. Bu POSTaşırı yükleme ve POSTaşırı yükleme RESTful değil, RPC-Style tasarımıdır.
acdcjunior

Eylem / yöntem mantığının sunucuda barındırılacağını varsayıyorum, başka çağrının amacı ne olurdu? Açıkladığınız durumda, katılıyorum, bu iyi bir tasarım olmaz. Ancak, eylemi gerçekleştiren yöntem veya alt yordam URI tarafından belirtilir (bu, bir URL'nin sonunda fiil olarak belirtilen bir eylem kaynağının yararlı ve RESTful olmasının birçoğu olsa da, çoğu buna karşı öneride bulunur).
Jacob Stevens

6
Cevap güncelledi. Biraz uzun çünkü kapsamlı bir açıklama gerekli görünüyordu ("REST hakkında temel bir anlayışım olduğunu unutmayın."). Mümkün olduğunca net hale getirmek bir tür mücadeleydi. Umarım bir şekilde faydalıdır.
acdcjunior

2
Harika bir açıklama, oy verdim ancak Konum başlığı 202 Kabul edilen yanıtta kullanılmamalıdır. Birçok insanın RFC'den yaptığı yanlış bir yorum gibi görünüyor. Bu kontrol stackoverflow.com/questions/26199228/...
Delmo

6

Daha önce cevap verdim, ancak bu cevap eski cevabımla çelişiyor ve bir çözüme varmak için çok farklı bir strateji izliyor. HTTP isteğinin REST ve HTTP'yi tanımlayan kavramlardan nasıl oluşturulduğunu gösterir. Veya PATCHyerine de kullanır .POSTPUT

REST kısıtlamaları, sonra HTTP bileşenleri, sonra olası bir çözümden geçer.

DİNLENME

REST, dağıtılabilir bir hiper ortam sistemine ölçeklendirilebilmesi için uygulanması amaçlanan bir dizi kısıtlamadır. Bir eylemi uzaktan kontrol etme bağlamında bunu anlamak için bile, bir eylemi uzaktan kontrol etmeyi, dağıtılmış bir hiper ortam sisteminin bir parçası olarak - birbirine bağlı bilgileri keşfetmek, görüntülemek ve değiştirmek için bir sistemin bir parçası olarak düşünmelisiniz. Bu, değerinden daha fazla sorun varsa, muhtemelen RESTful yapmaya çalışmak iyi olmaz. İstemci üzerinde yalnızca 80 numaralı bağlantı noktası üzerinden sunucudaki eylemleri tetikleyebilen bir "kontrol paneli" türü GUI istiyorsanız, muhtemelen HTTP istekleri / yanıtları veya bir WebSocket aracılığıyla JSON-RPC gibi basit bir RPC arabirimi istersiniz.

Ancak REST büyüleyici bir düşünme şeklidir ve sorudaki örnek RESTful bir arayüzle modellenmesi kolay olur, bu yüzden eğlence ve eğitim için meydan okumayı ele alalım.

REST, dört arabirim kısıtlamasıyla tanımlanır :

kaynakların tanımlanması; temsiller yoluyla kaynakların manipülasyonu; kendini tanımlayan mesajlar; ve uygulama durumunun motoru olarak hiper ortam.

Bir bilgisayarın başka bir bilgisayara köpek kabuğu yapmasını söylediği bu kısıtlamaları karşılayan bir arabirimi nasıl tanımlayabileceğinizi sorarsınız. Özellikle, arayüzünüzün HTTP olmasını istiyorsunuz ve istendiği gibi kullanıldığında HTTP RESTful yapan özellikleri silmek istemiyorsunuz.

İlk kısıtlama ile başlayalım: kaynak tanımlama .

Adlandırılabilecek herhangi bir bilgi bir kaynak olabilir: bir belge veya resim, geçici bir hizmet (ör. "Los Angeles'ta bugünün hava durumu"), diğer kaynakların bir koleksiyonu, sanal olmayan bir nesne (örn. Bir kişi), vb. .

Yani köpek bir kaynaktır. Tanımlanması gerekiyor.

Daha kesin olarak, bir R kaynağı geçici olarak değişen bir üyelik fonksiyonu M R ( t ) 'dir, bu zaman için t eşdeğer bir varlık veya değer kümesine eşlenir. Kümedeki değerler kaynak gösterimleri ve / veya kaynak tanımlayıcıları olabilir .

Sen modellemek tanımlayıcıları ve temsiller bir dizi alarak ve hepsi belirli bir zamanda birbiriyle ilişkili diyerek bir köpek. Şimdilik, "köpek # 1" tanımlayıcısını kullanalım. Bu bizi ikinci ve üçüncü kısıtlamalara getirir: kaynak gösterimi ve kendini tanımlama .

REST bileşenleri, o kaynağın geçerli veya amaçlanan durumunu yakalamak için bir temsil kullanarak ve bu gösterimi bileşenler arasında aktararak bir kaynak üzerinde eylem gerçekleştirir. Temsili bir bayt dizisi ve bu baytları tanımlamak için temsili meta verileridir.

Aşağıda, köpeğin amaçlanan durumunu yakalayan bir bayt dizisi, yani "köpek # 1" tanımlayıcısıyla ilişkilendirilmesini istediğimiz temsil dizisidir. ve hatta geçmiş kabuklar):

Bu durum değişikliğinin gerçekleştiği zamandan bu yana her 10 dakikada bir havlıyor ve süresiz olarak devam edecek.

Bunu tanımlayan meta verilere eklenmesi gerekiyor. Bu meta veriler yararlı olabilir:

İngilizce bir ifadedir. İstenen durumun bir bölümünü açıklar. Birden fazla kez alınırsa, yalnızca ilkinin bir etkisi olmasına izin verin.

Son olarak, dördüncü kısıtlamaya bakalım: HATEOAS .

REST ... bir uygulamayı, kullanıcının istediği görevi gerçekleştirebileceği bilgi ve kontrol alternatiflerinin uyumlu bir yapısı olarak görür. Örneğin, çevrimiçi bir sözlükte bir kelimeyi aramak, sanal bir müzede gezinmek veya bir sınava çalışmak için bir grup ders notunu gözden geçirmek gibi bir uygulamadır. ... Bir uygulamanın bir sonraki kontrol durumu, ilk istenen kaynağın temsilinde bulunur, bu nedenle ilk temsilin elde edilmesi bir önceliktir. ... Bu nedenle model uygulaması, mevcut temsiller kümesindeki alternatif durum geçişlerini inceleyerek ve seçerek bir durumdan diğerine hareket eden bir motordur.

RESTful arabiriminde, istemci bir temsili nasıl alması veya göndermesi gerektiğini bulmak için bir kaynak temsili alır. Uygulamada, müşterinin bu bilgilere ulaşmak için bir temsil zincirini izlese bile, alabilmesi veya gönderebilmesi gereken tüm temsilcilikleri nasıl alacağını veya gönderebileceğini anlayabileceği bir yerde bir temsil olmalıdır. Bu yeterince basit görünüyor:

Müşteri, ana sayfa olarak tanımlanan bir kaynağın temsilini ister; yanıt olarak, istemcinin isteyebileceği her köpeğin bir tanımlayıcısını içeren bir gösterim alır. İstemci ondan bir tanımlayıcı çıkarır ve hizmete, tanımlanmış köpekle nasıl etkileşime girebileceğini sorar ve hizmet, müşterinin köpeğin amaçlanan durumunun bir kısmını açıklayan bir İngilizce ifade gönderebileceğini söyler. Sonra istemci böyle bir ifade gönderir ve bir başarı mesajı veya bir hata mesajı alır.

HTTP

HTTP, REST kısıtlamalarını şu şekilde uygular:

kaynak kimliği : URI

kaynak gösterimi : varlık-gövde

kendi kendine açıklama : yöntem veya durum kodu, başlıklar ve varlık gövdesinin muhtemelen parçaları (ör. XML şemasının URI'si)

HATEOAS : köprüler

http://api.animals.com/v1/dogs/1URI olarak karar verdiniz . Müşterinin bunu sitedeki bazı sayfalardan aldığını varsayalım.

Let kullanımı bu işletme gövdesi (değerinin nextbir zaman damgası olduğu; değeri 0'Bu talep alındığında' vasıtasıyla):

{"barks": {"next": 0, "frequency": 10}}

Şimdi bir yönteme ihtiyacımız var. PATCH , karar verdiğimiz "amaçlanan durumun bir kısmı" açıklamasına uyar:

PATCH yöntemi, istek varlığında açıklanan bir dizi değişikliğin Request-URI tarafından tanımlanan kaynağa uygulanmasını ister.

Ve bazı başlıklar:

Varlık-kuruluşun dilini belirtmek için: Content-Type: application/json

Bunun yalnızca bir kez gerçekleştiğinden emin olmak için: If-Unmodified-Since: <date/time this was first sent>

Ve bir isteğimiz var:

PATCH /v1/dogs/1/ HTTP/1.1
Host: api.animals.com
Content-Type: application/json
If-Unmodified-Since: <date/time this was first sent>
[other headers]

{"barks": {"next": 0, "frequency": 10}}

Başarılı olduğunda, müşteri 204yanıt olarak bir durum kodu almalı veya bir 205temsili /v1/dogs/1/yeni havlama programını yansıtacak şekilde değişmişse.

Başarısızlık durumunda 403neden bir ve yararlı bir mesaj almalıdır .

Hizmetin kabuk çizelgesini yanıt olarak bir sunumda yansıtması REST için gerekli değildir GET /v1/dogs/1/, ancak bir JSON temsilinin bunu içermesi en mantıklı olacaktır:

"barks": {
    "previous": [x_1, x_2, ..., x_n],
    "next": x_n,
    "frequency": 10
}

Cron işine, sunucunun arabirimden gizlediği bir uygulama ayrıntısı olarak davranın. Genel bir arayüzün güzelliği budur. İstemci, sunucunun perde arkasında ne yaptığını bilmek zorunda değildir; önemli olan, hizmetin istenen durum değişikliklerini anlaması ve bunlara yanıt vermesidir.


3

Çoğu insan POST'u bu amaçla kullanır. "Başka hiçbir HTTP yöntemi uygun görünmediğinde güvenli olmayan veya önemsiz olmayan bir işlem" gerçekleştirmek için uygundur.

XMLRPC gibi API'ler , rasgele kod çalıştırabilecek eylemleri tetiklemek için POST kullanır . "Eylem" POST verilerine dahil edilir:

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

<?xml version="1.0"?>
<methodCall>
   <methodName>examples.getStateName</methodName>
   <params>
      <param>
         <value><i4>41</i4></value>
         </param>
      </params>
   </methodCall>

RPC, POST'un sunucu tarafı yöntemler için geleneksel HTTP fiil seçimi olduğunu göstermek için verilmiştir. İşte POST ile ilgili Roy Fielding düşünceleri - hemen hemen belirtilen HTTP yöntemlerini kullanmanın RESTful olduğunu söylüyor.

Kaynak odaklı olmadığı için RPC'nin kendisinin çok RESTful olmadığını unutmayın. Ancak vatansızlığa, önbelleğe veya katmanlamaya ihtiyacınız varsa, uygun dönüşümleri yapmak zor değildir. Örnek için bkz. Http://blog.perfectapi.com/2012/opinionated-rpc-apis-vs-restful-apis/ .


Ben sorgu dizesinde koymak params URLencode düşünüyorum
tacos_tacos_tacos

@Kirk Evet, ancak küçük bir değişiklikle son eğik çizgiyi bırakın: POST api.animals.com/v1/dogs1?action=bark
Raymond Hettinger

bu yanıttaki önerileri uygularsanız, ortaya çıkan API'nın RESTful olmayacağını unutmayın.
Nicholas Shanks

2
HTTP RESTful değildir çünkü HTTP URL'yi kaynağın tanımlayıcısı olarak belirler ve URL'si kaynağı /RPC2tanımlamak için hiçbir şey yapmaz - bir sunucu teknolojisini tanımlar. Bunun yerine, bu methodName, 'kaynağı' tanımlamak için kullanılır - ancak o zaman bile, isim / fiil ayrımından faydalanmaz; buradaki tek 'fiil' benzeri şey methodCall. Bu, 'durum adını al' yerine 'durum-adı-alma yap' gibidir; ikincisi çok daha mantıklıdır.
Ürdün

Bağlantılar için +1; çok bilgilendirici ve "görüşlü RPC" deneyi yaratıcıdır.
Ürdün

2

POSTolan HTTP yöntemi dizayn için

Veri işleme sürecine bir veri bloğu sağlama ...

CRUD ile eşlenmemiş eylemleri ele alan sunucu tarafı yöntemleri, Roy Fielding'in REST ile amaçladığı şeydir , bu yüzden orada iyisiniz ve bu yüzden POSTidempotent olmamak için yapıldı. POSTbilgilerin işlenmesi için çoğu veriyi sunucu tarafındaki yöntemlere gönderir.

Bununla birlikte, köpek havlayan senaryoda, her 10 dakikada bir sunucu tarafı bir kabuğun yapılmasını istiyorsanız, ancak bir nedenden dolayı tetikleyicinin bir istemciden kaynaklanması gerekiyorsa, PUTidempotence nedeniyle amaca daha iyi hizmet edecektir. Kesinlikle bu senaryoda, köpeğinizin miyavlamasına neden olan birden fazla POST isteği riski yoktur, ancak yine de iki benzer yöntemin amacı budur. Benzer bir SO sorusuna cevabım sizin için yararlı olabilir.


1
PUT ve POST tamamen URL ile ilgilidir. Sonra üçüncü paragraf 9.6 PUT iki yöntemden amacı böyledir diyor PUTURL olması gerektiğini ifade eder yerini müşterinin içerik ve POSTURL gerektiğini belirtmektedir işlemek istediği ancak müşterinin içeriği.
Ürdün

1

Barking'in tüketicinin hareket edebileceği bir iç / bağımlı / alt kaynak olduğunu varsayarsak, şöyle diyebiliriz:

POST http://api.animals.com/v1/dogs/1/bark

köpek sayısı 1

GET http://api.animals.com/v1/dogs/1/bark

son ağaç kabuğu zaman damgasını döndürür

DELETE http://api.animals.com/v1/dogs/1/bark

geçerli değil! bu yüzden görmezden gelin.


Bu, yalnızca kendi başına/v1/dogs/1/bark bir kaynak olduğunu ve bu kaynağın iç durumunun nasıl değişmesi gerektiğinin bir açıklaması olduğunu düşünüyorsanız RESTful olur . Sadece bir kaynak olarak düşünmenin ve varlık bedeninde havlanması gerektiğini belirtmenin daha anlamlı olduğunu düşünüyorum. POST/v1/dogs/1/
Ürdün

mmm .. şey, durumunu değiştirebileceğiniz bir kaynak. Durumunu değiştirmenin sonucu gürültü yapmaktır, daha az kaynak yapmaz! Bark'a bir fiil olarak bakıyorsunuz (yani) bu yüzden onu bir kaynak olarak göremezsiniz. Bunu, durumunun değiştirilebileceği bağımlı bir kaynak olarak görüyorum ve durumu boolean olduğundan, varlık-bedeninde bahsetmek için herhangi bir neden görmüyorum. Bu sadece benim görüşüm.
bolbol

1

Bazı yanıtların daha önceki sürümlerinde RPC kullanmanızı öneririz. REST kısıtlamalarına bağlı kalırken istediğinizi yapmak tamamen mümkün olduğu için RPC'ye bakmanıza gerek yoktur.

İlk olarak, URL'ye işlem parametreleri koymayın. URL , eylemi neye uyguladığınızı tanımlar ve sorgu parametreleri URL'nin bir parçasıdır. Tamamen bir isim olarak düşünülmelidir . http://api.animals.com/v1/dogs/1/?action=barkfarklı bir kaynaktır - farklı bir isim http://api.animals.com/v1/dogs/1/. [Asker kaldırdığı nb ?action=barksorusundan URI.] Örneğin, karşılaştırma http://api.animals.com/v1/dogs/?id=1için http://api.animals.com/v1/dogs/?id=2. Yalnızca sorgu dizesiyle ayırt edilen farklı kaynaklar. Bu nedenle, doğrudan gövdesiz bir mevcut yöntem türüne (TRACE, OPTIONS, HEAD, GET, DELETE, vb.) Karşılık gelmedikçe, isteğinizin eylemi istek gövdesinde tanımlanmalıdır.

Daha sonra, eylemin " idempotent " olup olmadığına karar verin , yani olumsuz etki olmadan tekrarlanabileceği anlamına gelir (daha fazla açıklama için bir sonraki paragrafa bakın). Örneğin, istemcinin istenen etkinin gerçekleştiğinden emin olmaması durumunda bir değerin true değerine ayarlanması tekrarlanabilir. İsteği tekrar gönderir ve değer doğru kalır. Bir sayıya 1 eklemek idempotent değildir. İstemci Add1 komutunu gönderirse, çalıştığından emin değil ve tekrar gönderirse, sunucu bir veya iki ekledi mi? Bunu belirledikten sonra , yönteminiz arasında PUTve POSTiçin seçim yapmak için daha iyi bir konumtasınız.

Idempotent, bir isteğin sonucu değiştirmeden tekrarlanabileceği anlamına gelir . Bu efektler günlüğe kaydetmeyi ve bu tür diğer sunucu yöneticisi etkinliklerini içermez. İlk ve ikinci örneklerinizi kullanarak, aynı kişiye iki e-posta göndermek, bir e-posta göndermekten farklı bir durumla sonuçlanır (alıcının gelen kutusunda iki tane spam olduğunu düşünebilecekleri iki tane vardır), bu yüzden kesinlikle POST'u kullanacağım . Örnek 2'deki barkCount'un API'nizin bir kullanıcısı tarafından görülmesi veya istemcinin görebileceği bir şeyi etkilemesi amaçlanıyorsa, aynı zamanda isteği idempotent olmayan bir şey de yapar. Yalnızca sizin tarafınızdan görüntülenecekse, sunucu günlüğü olarak sayılır ve idempotentcy belirlenirken yok sayılmalıdır.

Son olarak, gerçekleştirmek istediğiniz eylemin hemen başarılı olup olmayacağını belirleyin. BarkDog hızla tamamlanan bir eylemdir. RunMarathon değil. İşleminiz yavaşsa, 202 Acceptedbir kullanıcının eylemin tamamlanıp tamamlanmadığını görmek için yanıt gövdesinde bir URL olacak şekilde a döndürmeyi düşünün . Alternatif olarak, kullanıcıların bir liste URL'sine POST göndermelerini isteyin /marathons-in-progress/ve ardından işlem tamamlandığında, devam eden kimlik URL'sinden /marathons-complete/URL'ye yönlendirin.
Belirli durumlar için # 1 ve # 2, sunucunun bir kuyruk barındırmasını ve istemcinin adres gruplarını göndermesini isterim. Eylem SendEmails değil, AddToDispatchQueue gibi bir şey olacaktır. Sunucu daha sonra bekleyen e-posta adresleri olup olmadığını görmek için kuyruğu yoklayabilir ve bulursa e-posta gönderebilir. Ardından, bekleyen eylemin gerçekleştirildiğini göstermek için kuyruğu güncelleştirir. İstemciye sıranın geçerli durumunu gösteren başka bir URI'niz olur. E-postaların iki kez gönderilmesini önlemek için, sunucu aynı zamanda bu e-postayı kime gönderdiğinin günlüğünü tutabilir ve aynı listeyi iki kez POST ETMEDENİZ bile asla aynı adrese iki tane göndermediğinden emin olmak için her adresi kontrol edebilir. kuyruk.

Herhangi bir şey için bir URI seçerken, bunu bir eylem olarak değil, bir sonuç olarak düşünmeye çalışın. Örneğin google.com/search?q=dogs, "köpekler" kelimesine ilişkin bir aramanın sonuçlarını gösterir . Aramayı yapmanız gerekmez.

Listenizdeki 3 ve 4 numaralı davalar da idempotent eylemler değildir. Önerilen farklı efektlerin API tasarımını etkileyebileceğini önerirsiniz. Dört durumda da aynı API'yı kullanacağım, çünkü dördü de “dünya devletini” değiştiriyor.


Diyelim ki eylem, dev bir e-posta kuyruğunu dolaşmak ve bir grup kişiye mesaj göndermek. Bu idempotent mi? PUT veya POST için idempotent eylemler var mı?
Kirk Ouimet

@kirk Cevabımı genişlettim.
Nicholas Shanks

0

Yeni cevabımı görün - bununla çelişiyor ve REST ve HTTP'yi daha net ve doğru bir şekilde açıklıyor.

İşte RESTful olur ama kesinlikle tek seçenek değil bir öneri . Hizmet isteği aldığında havlamaya başlamak için:

POST /v1/dogs/1/bark-schedule HTTP/1.1
...
{"token": 12345, "next": 0, "frequency": 10}

token bu istek kaç kez gönderilirse gönderilsin gereksiz fazlalıkları önleyen rastgele bir sayıdır.

nextbir sonraki kabuğun zamanını gösterir; değeri 0vasıtası 'en kısa zamanda'.

Eğer zaman GET /v1/dogs/1/bark-schedule, böyle bir şey almalısınız, nereye t son kabuğu zamanıdır ve u ise t + 10 dakika:

{"last": t, "next": u}

Köpeğin mevcut havlama durumu hakkında bilgi edinmek için kullandığınız bir hav istemek için aynı URL'yi kullanmanızı şiddetle tavsiye ederim. REST için gerekli değildir, ancak programı değiştirme eylemini vurgular.

Uygun durum kodu muhtemelen 205'tir . Geçerli zamanlamaya bakan, POSTdeğiştirmek için aynı URL'ye s ve hizmet tarafından değiştirildiğini kanıtlamak için zamanlamaya ikinci bir görünüm vermek için talimat verilen bir istemci hayal ediyorum .

açıklama

DİNLENME

Bir an için HTTP'yi unutun. Bir kaynağın girdi olarak zaman alan ve tanımlayıcılar ve temsiller içeren bir küme döndüren bir işlev olduğunu anlamak önemlidir . Şunu basitleştirelim: bir kaynak, tanımlayıcılar ve temsiller kümesi R'dir ; R değişebilir - üyeler eklenebilir, kaldırılabilir veya değiştirilebilir. ( 'S kötü, dengesiz tasarım kaldırmak veya tanımlayıcıları değiştirin. Gitse dahi) Biz bir unsurdur bir tanımlayıcı söylemek R tanımlar R , ve bir unsurdur bir temsili olduğunu R temsil R .

Diyelim ki R bir köpek. Sen tanımlamak için ne R olarak /v1/dogs/1. (Anlamı /v1/dogs/1üyesidir Ar .) Yani tanımlamak izleyebileceği yollardan sadece biri Ar . Ayrıca teşhis edebilir R olarak /v1/dogs/1/x-raysve sıra /v1/rufus.

R'yi nasıl temsil ediyorsunuz ? Belki bir fotoğrafla. Belki bir dizi röntgen ile. Ya da belki R'nin son havladığı tarih ve saati gösterir . Ancak bunların hepsinin aynı kaynağın temsilleri olduğunu unutmayın . /v1/dogs/1/x-rays" R en son ne zaman havlandı?"

HTTP

İstediğiniz kaynağa başvuramazsanız, bir kaynağın birden fazla temsili çok yararlı değildir. Bu yüzden HTTP yararlıdır: tanımlayıcıları temsillere bağlamanızı sağlar . Yani, hizmetin bir URL alması ve istemciye hangi temsilin sunulacağına karar vermesinin bir yoludur.

En azından, bu GETböyle. PUTtemel olarak bunun tersidir GET: URL'ye gelecekteki r isteklerinin r döndürmesini istiyorsanız , JSON'dan HTML'ye gibi bazı çevirilerle URL'de PUTbir r temsili .GET

POSTbir temsili değiştirmenin daha gevşek bir yoludur. Her ikisi de aynı URL'ye karşılık gelen, birbirinin muadili olan görüntü mantığı ve değişiklik mantığı olduğunu düşünün. POST isteği, değişiklik mantığının bilgileri işlemesi ve hizmetin uygun gördüğü tüm gösterimleri (yalnızca aynı URL'de bulunan gösterimi değil) değiştirmesidir. 9.6 PUT'dan sonraki üçüncü paragrafa dikkat edin : URL'deki şeyi yeni içerikle değiştirmiyorsunuz; URL'deki şeyden bazı bilgileri işlemesini ve bilgilendirici temsiller biçiminde akıllıca yanıt vermesini istersiniz.

Bizim durumumuzda, bilgimizin /v1/dogs/1/bark-scheduleişlenmesini ve bazı temsillerini buna göre değiştirmesini sağlamak için adresindeki değişiklik mantığından (bu, en son ne zaman havlandığını ve ne zaman havlayacağını söyleyen görüntü mantığının karşılığıdır) isteriz. Geleceğe yanıt olarak GET, aynı URL'ye karşılık gelen görüntü mantığı, köpeğin şimdi istediğimiz gibi havladığını söyleyecektir.

Cron işini bir uygulama detayı olarak düşünün. HTTP, sunumları görüntüleme ve değiştirme ile ilgilenir. Bundan sonra, hizmet müşteriye köpeğin en son ne zaman havladığını ve ne zaman havlayacağını söyleyecektir. Hizmetin bakış açısından, bu dürüsttür, çünkü o zamanlar geçmiş ve planlanan cron işlerine karşılık gelir.


-1

REST, kaynak odaklı bir standarttır, RPC'de olduğu gibi eyleme dayalı değildir.

Sunucunuzun havlamasını istiyorsanız, JSON-RPC gibi farklı fikirlere veya websockets iletişimine bakmalısınız.

Bence RESTful tutmaya her çalışacağım başarısız olacak: bir parametre POSTile verebilir action, herhangi bir yeni kaynak oluşturmuyorsunuz, ancak yan etkileri olabilir, daha güvenlidir.


POST"veri işleme sürecine bir veri bloğu ... sağlamak" için tasarlanmıştır . Görünüşe göre birçok insan kaynakları eylemlerden ayırıyor, ama gerçekten eylemler sadece bir tür kaynak. Bir sunucuda bir eylem kaynağını çağırmak, hala önbelleğe alınabilir, modüler ve ölçeklenebilir tek tip bir arabirimdir. Ayrıca vatansızdır, ancak müşteri bir yanıt beklemek üzere tasarlanmışsa bu ihlal edilebilir. Ancak sunucuda "geçersiz yöntem" olarak adlandırmak Roy Fielding'in REST ile amaçladığı şeydir .
Jacob Stevens

Ben de tarif gibi benim cevap RPC sadece gerçekleştirmek için sunucu isteyen fikrine dayanmaktadır oysa siz REST can örtülü, sunucu andan itibaren, "İşleminizin tamamlandı" dan, söylemek sorarak bir eylemi gerçekleştirmek için neden eylem. İkisi de mantıklı, tıpkı zorunlu ve deklaratif programlamanın her ikisi de mantıklı.
Ürdün
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.