REST'te işlemler?


148

REST'te aşağıdaki kullanım durumunu nasıl uygulayacağınızı merak ediyorum. Kavramsal modelden ödün vermeden yapmak mümkün mü?

Tek bir işlem kapsamında birden çok kaynağı okuyun veya güncelleyin. Örneğin, Bob'un banka hesabından John'un hesabına 100 $ aktarın.

Anladığım kadarıyla, bunu uygulamanın tek yolu hile yapmaktır. John veya Bob ile ilişkili kaynağa POST yapabilir ve tüm işlemi tek bir işlem kullanarak gerçekleştirebilirsiniz. Endişelendiğim kadarıyla bu, REST mimarisini bozuyor, çünkü aslında bireysel kaynaklar üzerinde çalışmak yerine POST aracılığıyla bir RPC çağrısını tünelliyorsunuz.

Yanıtlar:


91

RESTful bir alışveriş sepeti senaryosu düşünün. Alışveriş sepeti kavramsal olarak işlem paketleyicinizdir. Bir alışveriş sepetine birden fazla ürün ekleyebilmeniz ve ardından siparişi işlemek için bu sepeti gönderebilmeniz gibi, Bob'un hesap girişini işlem sarmalayıcıya ve ardından Bill'in hesap girişini paketleyiciye ekleyebilirsiniz. Tüm parçalar yerinde olduğunda, işlem sarmalayıcısını tüm bileşen parçalarıyla birlikte POST / PUT edebilirsiniz.


18
TransferMoneyTransaction neden uygun bir bankacılık kaynağı olmasın?
Darrel Miller

8
Uç noktalarınızın isimleri ifade ettiğinden emin olursanız, genellikle standart GET, PUT, POST, DELETE fiillerinin o isme ne yapacağı sezgiseldir. RPC, uç noktaların fiil olmasına izin verir ve bu nedenle HTTP fiilleriyle çelişebilir ve amaç kafa karıştırıcı hale gelir.
Darrel Miller

10
örneğin UpdateXYZ uç noktasında bir HTTP SİLME yaparsanız ne olur? XYZ'yi siliyor mu? Güncellemeyi siliyor mu yoksa sadece bir Güncelleme yapıyor ve HTTP fiil silmeyi yok sayıyor mu? Fiilleri uç noktanın dışında tutarak kafa karışıklığını ortadan kaldırmış olursunuz.
Darrel Miller

5
Ve birden çok hizmet arasındaki işlemler ne olacak? ve hizmetin hiçbir örtük işlem kapsayıcısını göstermediği bir dizi 'ilgisiz' değişiklik yapmak istediğinizde ne olacak? artı, gerçek verilerinizle tamamen ilgisiz genel amaçlı işlemlere geçtiğimizde neden belirli bir işlem türünüz olsun? değişiklikler. İşlemler rahat eşleşmeyebilir, ancak işlemlerin üst üste katmanlanması gerekiyor gibi görünüyor, istek başlıklarının bir işlem referansı içereceği gerçeği dışında kalan çağrılarla ilgisi yok.
meandmycode

4
@meandmycode Veritabanı işlemleri bir REST arayüzünün arkasında katmanlanmalıdır. Alternatif olarak, bir ticari işlemi (bir veritabanı işlemini değil) kendi başına bir kaynak olarak ifşa edebilir ve ardından başarısızlık durumunda telafi edici eylemde bulunmanız gerekir.
Darrel Miller

60

Bu soruya cevap vermeyen birkaç önemli durum var ki çok kötü olduğunu düşünüyorum çünkü arama terimleri için Google'da üst sıralarda yer alıyor :-)

Spesifik olarak, güzel bir doğrusu şudur: Eğer iki kez POST yaparsanız (çünkü bazı önbellekler orta seviyede kesintiye uğrar), miktarı iki kez transfer etmemelisiniz.

Buna ulaşmak için, nesne olarak bir işlem yaratırsınız. Bu, zaten bildiğiniz tüm verileri içerebilir ve işlemi bekleme durumuna alabilir.

POST /transfer/txn
{"source":"john's account", "destination":"bob's account", "amount":10}

{"id":"/transfer/txn/12345", "state":"pending", "source":...}

Bu işlemi yaptıktan sonra, aşağıdakilere benzer bir şey yapabilirsiniz:

PUT /transfer/txn/12345
{"id":"/transfer/txn/12345", "state":"committed", ...}

{"id":"/transfer/txn/12345", "state":"committed", ...}

Bu noktada çoklu koymanın önemli olmadığını unutmayın; txn üzerindeki bir GET bile mevcut durumu döndürür. Spesifik olarak, ikinci PUT, ilkinin zaten uygun durumda olduğunu algılar ve onu geri döndürür - veya zaten "taahhütlü" duruma geldikten sonra "geri alma" durumuna koymaya çalışırsanız, bir hata ve gerçek taahhüt edilen işlem geri döndü.

Tek bir veritabanıyla veya entegre işlem izleyicili bir veritabanıyla konuştuğunuz sürece, bu mekanizma aslında gayet iyi çalışacaktır. Ek olarak, işlemler için zaman aşımları sunabilirsiniz, hatta isterseniz Expires başlıklarını kullanarak bile ifade edebilirsiniz.


İlginç tartışma! İlk gönderinin tek adımda yapılması gerektiğini eklemek isterim. Daha sonra eklenemez (o zaman alışveriş sepeti bölgesindeyiz ve alışveriş sepetlerinin son kullanıcıya zarar vermesini önlemek için birçok çek ve bakiyesi var, hatta mevzuat, banka havaleleri yapmaz) ...
Erk

33

REST terimlerinde, kaynaklar CRUD (oluşturma / okuma / güncelleme / silme) fiilleriyle kullanılabilen isimlerdir. "Para transferi" fiili olmadığından, CRUD ile üzerinde işlem yapılabilecek bir "işlem" kaynağı tanımlamamız gerekir. İşte HTTP + POX'ta bir örnek. İlk adım, yeni bir boş işlem OLUŞTURMAK (HTTP POST yöntemi) :

POST /transaction

Bu, örneğin "1234" ve URL "/ işlem / 1234" gibi bir işlem kimliği döndürür. Bu POST'u birden çok kez tetiklemenin birden çok kimlikle aynı işlemi oluşturmayacağını ve ayrıca "beklemede" durumunun başlatılmasını önleyeceğini unutmayın. Ayrıca, POST her zaman idempotent olamaz (bir REST gereksinimi), bu nedenle POST'lardaki verileri en aza indirmek genellikle iyi bir uygulamadır.

İşlem kimliğinin oluşturulmasını müşteriye bırakabilirsiniz. Bu durumda, "1234" işlemini oluşturmak için POST / işlem / 1234 yaparsınız ve sunucu zaten varsa bir hata döndürür. Hata yanıtında, sunucu şu anda kullanılmayan bir kimliği uygun bir URL ile döndürebilir. GET hiçbir zaman sunucu durumunu değiştirmemelidir ve yeni bir kimlik oluşturmak / ayırmak sunucu durumunu değiştireceğinden, sunucuyu GET yöntemiyle yeni bir kimlik için sorgulamak iyi bir fikir değildir.

Daha sonra, işlemi tüm verilerle GÜNCELLE (PUT HTTP yöntemi) örtük olarak taahhüt ederiz :

PUT /transaction/1234
<transaction>
  <from>/account/john</from>
  <to>/account/bob</to>
  <amount>100</amount>
</transaction>

Daha önce "1234" kimliğine sahip bir işlem PUT ise, sunucu bir hata yanıtı, aksi takdirde bir OK yanıtı ve tamamlanan işlemi görüntülemek için bir URL verir.

Not: / account / john içinde, "john" gerçekten John'un benzersiz hesap numarası olmalıdır.


4
REST'i CRUD ile eşitlemek ciddi bir hatadır. POST, CREATE anlamına gelmek zorunda değildir.

13
Ciddi hata mı? PUT ve POST arasında farklılıklar olduğunu biliyorum, ancak CRUD için gevşek bir eşleme var. "Ciddi anlamda"?
Ted Johnson

3
Evet cidden. CRUD, veri depolamayı yapılandırmanın bir yoludur; REST, uygulama veri akışını yapılandırmanın bir yoludur. REST'te CRUD yapabilirsiniz, ancak CRUD'da REST yapamazsınız. Eşdeğer değiller.
Jon Watte

20

Harika soru, REST çoğunlukla bir şeyin depolandığı, güncellendiği, alındığı, silindiği veritabanı benzeri örneklerle açıklanıyor. Sunucunun verileri bir şekilde işlemesinin beklendiği bunun gibi birkaç örnek var. Roy Fielding'in http'ye dayanan tezine herhangi bir şey dahil ettiğini sanmıyorum.

Ancak, bağlantıların bir sonraki duruma hareket ettiği bir durum makinesi olarak "temsili durum aktarımı" ndan söz ediyor. Bu şekilde, belgeler (temsiller) sunucunun yapmak zorunda kalması yerine, istemcinin durumunu takip eder. Bu şekilde, müşteri durumu yoktur, yalnızca hangi bağlantıda olduğunuzu belirtin.

Bunu düşünüyordum ve bana göre, sunucunun sizin için bir şeyi işlemesini sağlamak için, yüklediğinizde sunucunun otomatik olarak ilgili kaynakları oluşturması ve size bunlara bağlantılar vermesi makul görünüyor (aslında, Bunları otomatik olarak oluşturmaya gerek yoktur: size sadece bağlantıları söyleyebilir ve onları yalnızca ne zaman ve takip ederseniz oluşturur - tembel oluşturma). Ayrıca size yeni ilgili kaynaklar oluşturmak için bağlantılar vermek için - ilgili bir kaynak aynı URI'ye sahiptir ancak daha uzundur (bir son ek ekler). Örneğin:

  1. Tüm bilgilerle birlikte bir işlem konseptinin temsilini yüklersiniz ( POST ) . Bu tıpkı bir RPC çağrısına benziyor, ancak gerçekten "önerilen işlem kaynağını" yaratıyor. Örneğin, URI: /transaction Hatalar, her biri farklı bir URI'ye sahip olan bu tür birden çok kaynağın oluşturulmasına neden olacaktır.
  2. Sunucunun yanıtı, oluşturulan kaynağın URI'sini, temsilini belirtir - bu, yeni bir "taahhüt edilmiş işlem kaynağının" ilgili kaynağını oluşturmak için bağlantıyı ( URI ) içerir . Diğer ilgili kaynaklar, önerilen işlemi silme bağlantısıdır. Bunlar, müşterinin takip edebileceği durum makinesindeki durumlardır. Mantıksal olarak, bunlar, istemcinin sağladığı bilgilerin ötesinde, sunucuda oluşturulan kaynağın bir parçasıdır. örneğin URI'ları: /transaction/1234/proposed, /transaction/1234/committed
  3. Sunucunun durumunu değiştirerek (iki hesabın bakiyeleri) bu kaynağı oluşturan "taahhüt edilen işlem kaynağını" oluşturmak için bağlantıya POST yaparsınız **. Doğası gereği, bu kaynak yalnızca bir kez oluşturulabilir ve güncellenemez. Bu nedenle, birçok işlemi gerçekleştiren hatalar oluşmaz.
  4. Durumlarının ne olduğunu görmek için bu iki kaynağı ALABİLİRSİNİZ. Bir POST'un diğer kaynakları değiştirebileceğini varsayarsak, teklif artık "tamamlandı" (veya belki de hiç mevcut değil) olarak işaretlenecektir.

Bu, web sayfalarının nasıl çalıştığına benzer ve son web sayfası "Bunu yapmak istediğinizden emin misiniz?" Bu son web sayfasının kendisi, işlemin durumunun bir temsilidir ve bir sonraki duruma gitmek için bir bağlantı içerir. Sadece finansal işlemler değil; ayrıca (örneğin) önizleyin ve wikipedia'da kesin. Sanırım REST'teki ayrım, durum dizisindeki her aşamanın açık bir adı (URI'si) olmasıdır.

Gerçek hayattaki işlemlerde / satışlarda, bir işlemin farklı aşamaları için (teklif, satın alma emri, giriş vb.) Genellikle farklı fiziksel belgeler vardır. Yerleşimle vb. Ev satın almak için daha da fazlası

OTOH Bu bana anlambilimle oynamak gibi geliyor; "Fiiller (RPC çağrıları) yerine isimler (URI'ler) kullandığı için" fiilleri RESTful yapmak için isimlere dönüştürmenin nominalizasyonundan rahatsızım. yani "bu işlemi işle" fiili yerine "taahhüt edilmiş işlem kaynağı" adı. Sanırım nominalleştirmenin bir avantajı, başka bir şekilde belirtmek yerine kaynağa ismiyle başvurabilmenizdir (örneğin oturum durumunu sürdürmek, böylece "bu" işlemin ne olduğunu bilirsiniz ...)

Ancak önemli soru şudur: Bu yaklaşımın faydaları nelerdir? yani, bu REST stili, RPC stilinden ne şekilde daha iyidir? Web sayfaları için harika olan bir teknik, depolamak / almak / güncellemek / silmek dışında bilgi işlemede de yararlı mıdır? REST'in temel faydasının ölçeklenebilirlik olduğunu düşünüyorum; bunun bir yönü, istemci durumunu açıkça sürdürmek zorunda değildir (ancak bunu kaynağın URI'sinde ve sonraki durumları temsilinde bağlantılar olarak örtük hale getirir). Bu anlamda yardımcı oluyor. Belki de bu katmanlama / ardışık düzen oluşturmada yardımcı olur? OTOH yalnızca bir kullanıcı kendi özel işlemine bakacaktır, bu yüzden önbelleğe almanın hiçbir avantajı yoktur, böylece diğerleri okuyabilir, http için büyük kazanç.


"İstemcide durumu korumaya gerek kalmamasının" ölçeklenebilirliğe nasıl yardımcı olduğunu açıklar mısınız? Ne tür bir ölçeklenebilirlik? Hangi anlamda ölçeklenebilirlik?
jhegedus

11

Buradaki tartışmayı özetlemek için geri çekilirseniz, REST'in birçok API için uygun olmadığı oldukça açıktır, özellikle de istemci-sunucu etkileşimi, önemsiz olmayan işlemlerde olduğu gibi, doğası gereği durum bilgili olduğunda. Soruna uymayan bazı ilkeleri bilgiççe takip etmek için hem istemci hem de sunucu için önerilen tüm çemberleri neden atlayasınız? Daha iyi bir ilke, müşteriye uygulamayla beste yapmanın en kolay, en doğal ve verimli yolunu vermektir.

Özetle, uygulamanızda gerçekten çok sayıda işlem (tür, örnek değil) yapıyorsanız, gerçekten bir RESTful API oluşturmamanız gerekir.


9
Doğru, ama dağıtılmış mikro hizmet mimarisi durumunda bir alternatif ne olmalı?
Vitamon

11

10 yıldır bu konudan uzaklaştım. Geri dönersek, google rest + güvenilir olduğunuzda dinin bilim kılığına girdiğine inanamıyorum. Kafa karışıklığı efsanevi.

Bu geniş soruyu üçe ayırırdım:

  • Aşağı akış hizmetleri. Geliştirdiğiniz herhangi bir web hizmeti, kullandığınız ve işlem sözdizimini takip etmekten başka seçeneğiniz olmayan aşağı akış hizmetlerine sahip olacaktır. Tüm bunları hizmetinizin kullanıcılarından saklamaya çalışmalı ve işleminizin tüm bölümlerinin grup olarak başarılı veya başarısız olduğundan emin olmalı ve ardından bu sonucu kullanıcılarınıza iade etmelisiniz.
  • Hizmetleriniz. Müşteriler, web hizmeti aramalarında kesin sonuçlar istiyorlar ve POST, PUT veya DELETE taleplerini doğrudan önemli kaynaklar üzerinde yapmanın olağan DİNLENME modeli, bu kesinliği sağlamanın zayıf ve kolayca iyileştirilmiş bir yolu olarak beni etkiliyor. Güvenilirliği önemsiyorsanız, eylem taleplerini belirlemeniz gerekir. Bu kimlik, istemcide oluşturulan bir kılavuz veya sunucudaki ilişkisel bir DB'den bir çekirdek değer olabilir, önemli değil. Sunucu tarafından oluşturulan kimlikler için, eylemin kimliğini değiştirmek için bir 'ön kontrol' istek yanıtı kullanın. Bu istek başarısız olursa veya yarısı başarılı olursa, sorun değil, istemci yalnızca isteği tekrarlar. Kullanılmayan kimlikler zarar vermez.

    Bu önemlidir, çünkü sonraki tüm isteklerin tamamen idempotent olmasını sağlar, yani n kez tekrarlanırlarsa aynı sonucu döndürürler ve başka hiçbir şeyin olmamasına neden olmazlar. Sunucu tüm yanıtları eylem kimliğine göre depolar ve aynı isteği görürse aynı yanıtı yeniden oynatır. Bu Google dokümanında modelin daha kapsamlı bir anlatımı yer almaktadır . Doküman, inanıyorum ki (!), Genel olarak REST prensiplerini izleyen bir uygulama önermektedir. Uzmanlar bana bunun başkalarını nasıl ihlal ettiğini kesinlikle söyleyecekler. Bu model, ilgili aşağı akış işlemleri olsun veya olmasın, web hizmetinize güvenli olmayan herhangi bir çağrı için faydalı bir şekilde kullanılabilir.
  • Hizmetinizin yukarı akış hizmetleri tarafından kontrol edilen "işlemlere" entegrasyonu. Web hizmetleri bağlamında, tam ACID işlemleri genellikle çabaya değmez olarak kabul edilir, ancak onay yanıtınızda iptal ve / veya onay bağlantıları sağlayarak hizmetinizin tüketicilerine büyük ölçüde yardımcı olabilir ve böylece tazminat yoluyla işlem gerçekleştirebilirsiniz .

İhtiyacınız temeldir. İnsanların size çözümünüzün koşer olmadığını söylemesine izin vermeyin. Mimarilerini, sorununuzu ne kadar iyi ve ne kadar basit bir şekilde ele aldıklarına göre değerlendirin.


9

Kendi "işlem kimliği" türünüzü tx yönetimi devralmanız gerekir. Yani 4 arama olur:

http://service/transaction (some sort of tx request)
http://service/bankaccount/bob (give tx id)
http://service/bankaccount/john (give tx id)
http://service/transaction (request to commit)

Eylemlerin bir DB'de (yük dengeli ise) veya bellekte saklanmasını, ardından commit, rollback, timeout işlemlerini yapmanız gerekir.

Parkta gerçekten DİNLENEN bir gün değil.


4
Bunun özellikle iyi bir örnek olduğunu sanmıyorum. Yalnızca iki adıma ihtiyacınız vardır: İşlem oluşturma ("beklemede" durumunda bir işlem oluşturur) ve İşlemi tamamla (taahhüt edilmemişse taahhüt eder ve kaynağı taahhüt edilmiş veya geri alınmış durumuna taşır).
Jon Watte

2

Bu durumda, bu durumda REST'in saf teorisini kırmanın tamamen kabul edilebilir olduğunu düşünüyorum. Her halükarda, REST'te bunu gerektiren iş vakalarında bağımlı nesnelere dokunamayacağınızı söyleyen bir şey olduğunu sanmıyorum.

Bunu yapmak için sadece veritabanından yararlanabildiğiniz zaman, özel bir işlem yöneticisi oluşturmak için atlayacağınız fazladan çemberlere değmeyeceğini düşünüyorum.


2

Öncelikle para transferi, tek bir kaynak çağrısında yapamayacağınız bir şey değildir. Yapmak istediğiniz eylem para göndermektir. Böylece gönderenin hesabına bir para transferi kaynağı eklersiniz.

POST: accounts/alice, new Transfer {target:"BOB", abmount:100, currency:"CHF"}.

Bitti. Bunun atomik vb. Olması gereken bir işlem olduğunu bilmenize gerek yok. Sadece para transfer edersiniz. A'dan B'ye para gönderin.


Ancak buradaki ender durumlar için genel bir çözüm:

Pek çok kaynağı tanımlanmış bir bağlamda içeren çok karmaşık bir şey yapmak istiyorsanız, aslında neye karşı neden engelini aşan birçok kısıtlama (iş ve uygulama bilgisi) durumu aktarmanız gerekir. REST, vatansız olması gerektiğinden, bir müşteri olarak eyaleti başka bir yere aktarmanız gerekir.

Durumu aktarırsanız, içindeki bilgileri istemciden gizlemeniz gerekir. Müşteri, yalnızca uygulama için gerekli olan dahili bilgileri bilmemeli, ancak iş açısından ilgili bilgileri taşımamalıdır. Bu bilgilerin ticari değeri yoksa, devlet şifrelenmeli ve simge, geçiş veya benzeri bir metafor kullanılması gerekir.

Bu yolla kişi dahili durumu geçirebilir ve şifreleme ve sistem imzalama hala güvenli ve sağlam olabilir. Müşteri için neden durum bilgisini aktardığını doğru soyutlamayı bulmak, tasarım ve mimariye bağlı bir şeydir.


Gerçek çözüm:

REST'in HTTP'den bahsettiğini ve HTTP'nin çerez kullanma konseptiyle geldiğini unutmayın. Bu çerezler, insanlar REST API ve birden çok kaynağı veya isteği kapsayan iş akışları ve etkileşimler hakkında konuştuğunda genellikle unutulur.

Wikipedia'da HTTP çerezleri hakkında yazılanları hatırlayın:

Çerezler, web sitelerinin durum bilgisi olan bilgileri (bir alışveriş sepetindeki öğeler gibi) hatırlaması veya kullanıcının göz atma faaliyetini (belirli düğmeleri tıklama, oturum açma veya kullanıcı tarafından o ana kadar hangi sayfaların ziyaret edildiğini kaydetme dahil) kaydetmesi için güvenilir bir mekanizma olarak tasarlanmıştır. aylar veya yıllar önce).

Dolayısıyla, temelde durumu iletmeniz gerekiyorsa, bir çerez kullanın. Tam olarak aynı sebep için tasarlanmıştır, HTTP'dir ve bu nedenle tasarım gereği REST ile uyumludur :).


Daha iyi çözüm:

Birden fazla isteği içeren bir iş akışını gerçekleştiren bir müşteriden bahsediyorsanız, genellikle protokol hakkında konuşursunuz. Her protokol biçimi, B'yi yapmadan önce A adımını gerçekleştirmek gibi her potansiyel adım için bir dizi ön koşulla birlikte gelir.

Bu doğaldır ancak protokolü istemcilere açıklamak her şeyi daha karmaşık hale getirir. Bundan kaçınmak için, gerçek dünyada karmaşık etkileşimler ve şeyler yapmamız gerektiğinde ne yaptığımızı bir düşünün ... Bir Ajan kullanıyoruz.

Temsilci metaforunu kullanarak, sizin için gerekli tüm adımları gerçekleştirebilecek ve uyguladığı fiili atamayı / talimatları kendi listesinde saklayabilecek bir kaynak sağlayabilirsiniz (böylece POST'u temsilci veya bir 'ajans' üzerinde kullanabiliriz).

Karmaşık bir örnek:

Bir ev satın almak:

Güvenilirliğinizi kanıtlamanız (polis kaydı girişlerinizi sağlamak gibi), finansal ayrıntıları sağlamanız, gerçek evi bir avukat ve parayı saklayan güvenilir bir üçüncü kişi aracılığıyla satın almanız, evin artık size ait olduğunu doğrulamanız ve satın alma malzemelerini vergi kayıtlarınıza vb. ekleyin (örnek olarak, bazı adımlar yanlış veya her neyse)

Bu adımların tamamlanması birkaç gün sürebilir, bazıları paralel olarak yapılabilir vb.

Bunu yapmak için, acenteye ev satın alma görevi vermeniz yeterli:

POST: agency.com/ { task: "buy house", target:"link:toHouse", credibilities:"IamMe"}.

Bitti. Acente, size bu işin durumunu görmek ve takip etmek için kullanabileceğiniz bir referans gönderir ve geri kalanı ajans temsilcileri tarafından otomatik olarak yapılır.

Örneğin bir hata izleyiciyi düşünün. Temel olarak hatayı rapor edersiniz ve neler olup bittiğini kontrol etmek için hata kimliğini kullanabilirsiniz. Bu kaynaktaki değişiklikleri dinlemek için bir hizmet bile kullanabilirsiniz. Görev Tamamlandı.


1

REST'te sunucu tarafı işlemleri kullanmamalısınız.

REST bölümlerinden biri:

Vatansız

İstemci-sunucu iletişimi, istekler arasında sunucuda hiçbir istemci bağlamının depolanmaması nedeniyle daha da kısıtlanır. Herhangi bir müşteriden gelen her talep, talebe hizmet etmek için gerekli tüm bilgileri içerir ve herhangi bir oturum durumu istemcide tutulur.

Tek RESTful yolu, bir işlem yineleme günlüğü oluşturmak ve bunu istemci durumuna koymaktır. Talepler ile müşteri yineleme günlüğünü gönderir ve sunucu işlemi yeniden yapar ve

  1. işlemi geri alır ancak yeni bir işlem yineleme günlüğü sağlar (bir adım daha ileri)
  2. veya sonunda işlemi tamamlayın.

Ancak, sunucu tarafı işlemlerini destekleyen sunucu oturumu tabanlı bir teknoloji kullanmak belki daha kolaydır.


Alıntı wikipedia REST girişindendir. Bu gerçek kaynak mı yoksa wikipedia onu bir yerden mi aldı? İstemci bağlamının ne olduğunu ve sunucu bağlamının ne olduğunu kim söyleyebilir?
bbsimonbb

1

Bunun, bağlantı hıçkırığının API tarafından kaydedilen bir yineleme anlamına gelmemesini sağlamak için istemcide oluşturulan benzersiz bir tanımlayıcı kullanılması durumunda olacağına inanıyorum.

Transfer nesnesiyle birlikte müşteri tarafından oluşturulan bir GUID alanını kullanmanın ve aynı GUID'in tekrar yerleştirilmemesini sağlamanın banka havalesi konusunda daha basit bir çözüm olacağını düşünüyorum.

Birden çok uçak bileti rezervasyonu veya mikro mimariler gibi daha karmaşık senaryolar hakkında bilgi sahibi değilsiniz.

Konuyla ilgili, RESTful hizmetlerinde işlem atomikliği ile başa çıkma deneyimleriyle ilgili bir makale buldum .


0

Basit durumda (dağıtılmış kaynaklar olmadan), işlemi, onu yaratma eyleminin nihai hedefe ulaştığı bir kaynak olarak düşünebilirsiniz.

Yani, aralarında aktarmak <url-base>/account/ave <url-base>/account/bsize aşağıdakileri sonrası olabilir, <url-base>/transfer.

<transfer>
    <from> <url-base> / hesap / a </from>
    <to> <url-base> / hesap / b </to>
    <amount> 50 </amount>
</transfer>

Bu, yeni bir aktarım kaynağı oluşturur ve örneğin aktarımın yeni url'sini döndürür <url-base>/transfer/256.

Başarılı gönderi anında, daha sonra, sunucuda 'gerçek' işlem gerçekleştirilir ve miktar bir hesaptan kaldırılarak diğerine eklenir.

Ancak bu, dağıtılmış bir işlemi kapsamaz (bir hizmetin arkasındaki bir bankada 'a' tutulursa ve 'b' başka bir hizmetin arkasındaki başka bir bankada tutulursa) - "tümünü ifade etmeye çalışın" demek dışında dağıtılmış işlemler gerektirmeyen şekillerde işlemler ".


2
"Tüm işlemleri dağıtılmış işlemler gerektirmeyen şekillerde ifade edemiyorsanız", gerçekten iki aşamalı bir tamamlamaya ihtiyacınız var demektir. REST'te iki aşamalı kesinleştirme uygulamak için bulabildiğim en iyi fikir rest.blueoxen.net/cgi-bin/wiki.pl?TwoPhaseCommit'tir , bu önemli bir şekilde URL ad alanını bozmaz ve iki aşamalı bir tamamlamanın katmanlanmasına izin verir. temiz REST semantiği.
Phasmal

3
Bu öneriyle ilgili diğer sorun, bir önbellek hıçkırıklığı ve POST iki kez olursa, iki aktarım elde edeceğinizdir.
Jon Watte

Doğru, bu durumda iki aşamalı bir sürece sahip olmanız gerekir - benzersiz bir URL'ye sahip bir "aktarım" kaynağı oluşturun ve ardından aktarım ayrıntılarını kaydetmenin bir parçası olarak ekleyin (diğer yanıtlarda belirtildiği gibi iki bölüm). Tabii ki, bu daha sonra bir "işlem" kaynağı oluşturmak ve ardından ona bir "transfer" işlemi eklemek olarak ifade edilebilir.
Phasmal

-3

TAN'ı URL'ye / kaynağa ekleyebileceğinizi tahmin ediyorum:

  1. Kimliği almak için PUT / işlem (ör. "1")
  2. [PUT, GET, POST, ne olursa olsun] / 1 / hesap / bob
  3. [PUT, GET, POST, ne olursa olsun] / 1 / hesap / fatura
  4. DELETE / ID 1 ile işlem

Sadece bir fikir.


Bu yaklaşımla ilgili iki sorun görüyorum: 1) Bu, bir işlemin dışındaki bir kaynağa erişemeyeceğiniz anlamına gelir (belki de bu önemli bir şey değildir). 2) Şimdiye kadarki cevapların hiçbiri, sunucunun artık vatansız olmadığı gerçeğine değinmedi, ancak bu konuda hiçbir şey yapılamayacağından şüpheleniyorum.
Gili

Eh, / 1 / account / bob ve / account / bob sadece iki farklı kaynak. :) Ve RE: durumsuz, kaynağın her zaman kullanılabilir olduğunu ve önceki bir isteğe bağlı olmadığını gösterir. İşlemleri talep ettiğiniz için, evet durum böyle değil. Ama sonra yine işlem istedin.
kadar

1
Bir istemcinin URI'leri bir araya getirmesi gerekiyorsa, API'niz RESTful değildir.
aehlke

1
Sizi gerçekten anlayamıyorum çocuklar! Bir işlemi bir kaynak olarak ele alırsanız (yukarıdaki örnekte olduğu gibi), işlemi klasik anlamda işlemeyi bırakırsınız ve işlem süreçlerini programlamayı daha da basitleştiren "uygun REST yöntemiyle" kullanırsınız. Örneğin, dağıtılmış sunucu tarafı ortamında yer değiştirmenin etrafından dolaşmak için yanıtlarınıza bir href ekleyebilirsiniz, hala durumsuzdur (bu sadece bir kaynak, değil mi?) Ve yine de gerçek işlem mekanizmasını uygulayabilirsiniz. istiyorum (ya arkada bir DB yoksa?)
Matthias Hryniszak

1
Öyle ya da böyle SQL /
SOAP'ı
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.