REST में लेनदेन?


147

मुझे आश्चर्य है कि आप REST में निम्नलिखित उपयोग-मामले को कैसे लागू करेंगे। क्या वैचारिक मॉडल से समझौता किए बिना ऐसा करना संभव है?

एकल लेनदेन के दायरे में कई संसाधनों को पढ़ें या अपडेट करें। उदाहरण के लिए, बॉब के बैंक खाते से $ 100 को जॉन के खाते में स्थानांतरित करें।

जहां तक ​​मैं बता सकता हूं, इसे लागू करने का एकमात्र तरीका धोखा है। आप जॉन या बॉब से जुड़े संसाधन के लिए पोस्ट कर सकते हैं और एकल लेनदेन का उपयोग करके पूरे ऑपरेशन को अंजाम दे सकते हैं। जहां तक ​​मेरा सवाल है कि यह REST आर्किटेक्चर को तोड़ता है क्योंकि आप वास्तव में व्यक्तिगत संसाधनों पर काम करने के बजाय POST के माध्यम से RPC कॉल को टनलिंग कर रहे हैं।

जवाबों:


91

एक रेस्टफुल शॉपिंग बास्केट परिदृश्य पर विचार करें। खरीदारी की टोकरी वैचारिक रूप से आपके लेनदेन का आवरण है। उसी तरह जिस तरह आप एक खरीदारी की टोकरी में कई आइटम जोड़ सकते हैं और फिर ऑर्डर को संसाधित करने के लिए उस टोकरी को जमा कर सकते हैं, आप लेनदेन रैपर में बॉब के खाते में प्रवेश और फिर रैपर में बिल के खाते में प्रवेश कर सकते हैं। जब सभी टुकड़े जगह में हो जाते हैं तो आप सभी घटक टुकड़ों के साथ लेन-देन के रैपर को POST / PUT कर सकते हैं।


18
TransferMoneyTransaction एक व्यवहार्य बैंकिंग संसाधन क्यों नहीं होगा?
डारेल मिलर

8
यदि आपका सुनिश्चित करता है कि आपके समापन बिंदु संज्ञाओं को संदर्भित करते हैं तो यह आमतौर पर सहज है कि मानक GET, PUT, POST, DELETE क्रिया उस संज्ञा के लिए क्या करेगा। आरपीसी एंडपॉइंट्स को स्वयं क्रिया करने की अनुमति देता है और इसलिए वे HTTP क्रियाओं के साथ संघर्ष कर सकते हैं और इरादा भ्रमित हो जाता है।
डारेल मिलर

10
उदा। यदि आप समापन बिंदु UpdateXYZ पर HTTP DELETE करते हैं तो क्या होता है? क्या यह XYZ को हटाता है? क्या यह अपडेट को डिलीट करता है या यह सिर्फ एक अपडेट करता है और HTTP वर्ब डिलीट को नजरअंदाज करता है। क्रिया को समापन बिंदु से बाहर रखकर आप भ्रम को दूर करते हैं।
डारेल मिलर

5
और कई सेवाओं में लेनदेन के बारे में क्या? और जब आप 'असंबंधित ’परिवर्तनों का एक सेट करना चाहते हैं, तो सेवा बिना किसी निहित लेन-देन कंटेनर को उजागर करती है .. साथ ही, एक विशिष्ट लेनदेन प्रकार क्यों होता है जब हम सामान्य प्रयोजन लेनदेन में स्थानांतरित हो जाते हैं जो आपके वास्तविक डेटा से पूरी तरह से असंबंधित होते हैं। परिवर्तन। लेन-देन आराम से मेल नहीं खा सकते हैं, लेकिन ऐसा लगता है कि लेन-देन को ऑनटॉप स्तरित किया जाना चाहिए, बाकी कॉल के लिए असंबंधित इस तथ्य के अलावा अनुरोध हेडर में लेनदेन का संदर्भ होगा।
मेन्डमाइकोड

4
@meandmycode डेटाबेस लेनदेन को REST इंटरफ़ेस के पीछे रखना चाहिए। वैकल्पिक रूप से आप अपने आप में एक व्यापार लेनदेन (डेटाबेस लेनदेन नहीं) को एक संसाधन के रूप में उजागर कर सकते हैं और फिर आपको विफलता के मामले में क्षतिपूर्ति कार्रवाई करने की आवश्यकता है।
डारेल मिलर

60

कुछ महत्वपूर्ण मामले हैं जो इस प्रश्न का उत्तर नहीं देते हैं, जो मुझे लगता है कि बहुत बुरा है, क्योंकि यह खोज के लिए Google पर उच्च रैंकिंग है :-)

विशेष रूप से, एक अच्छा उचित रूप से यह होगा: यदि आप दो बार POST करते हैं (क्योंकि कुछ कैश मध्यवर्ती में hiccupped है) तो आपको राशि को दो बार स्थानांतरित नहीं करना चाहिए।

इसे प्राप्त करने के लिए, आप एक ऑब्जेक्ट के रूप में एक लेनदेन बनाते हैं। इसमें वह सभी डेटा शामिल हो सकते हैं जिन्हें आप पहले से जानते हैं, और लेनदेन को लंबित स्थिति में डालते हैं।

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

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

एक बार जब आपके पास यह लेनदेन होता है, तो आप इसे कर सकते हैं, जैसे कुछ:

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

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

ध्यान दें कि इस बिंदु पर कई पुट मायने नहीं रखते हैं; यहां तक ​​कि txn पर एक GET भी वर्तमान स्थिति लौटाएगा। विशेष रूप से, दूसरा PUT यह पता लगाएगा कि पहले से ही उपयुक्त स्थिति में था, और बस इसे वापस कर दें - या, यदि आप "प्रतिबद्ध" स्थिति में आने के बाद इसे "रोलबैक" स्थिति में डालने का प्रयास करते हैं, तो आपको एक मिलेगा त्रुटि, और वास्तविक प्रतिबद्ध लेनदेन वापस।

जब तक आप एकल डेटाबेस, या एक एकीकृत लेनदेन मॉनिटर के साथ डेटाबेस से बात करते हैं, यह तंत्र वास्तव में ठीक काम करेगा। आप इसके अतिरिक्त लेन-देन के लिए समय-समय पर परिचय दे सकते हैं, जिसे आप चाहते थे कि आप समय सीमा समाप्त करने वाले हेडर का उपयोग करके भी व्यक्त कर सकते हैं।


दिलचस्प चर्चा! मैं यह जोड़ना चाहता हूं कि प्रारंभिक पोस्ट एक चरण में किया जाना चाहिए। इसे बाद में नहीं जोड़ा जा सकता (तब हम शॉपिंग-कार्ट क्षेत्र में हैं और शॉपिंग कार्ट में कई चेक और बैलेंस हैं, जिससे उन्हें अंत उपयोगकर्ता को नुकसान पहुंचाने से रोका जा सके, यहां तक ​​कि कानून, बैंक हस्तांतरण भी नहीं होता है) ...
Erk

33

बाकी शब्दों में, संसाधन वे संज्ञाएं हैं जिन पर CRUD (क्रिएट / रीड / अपडेट / डिलीट) क्रियाओं के साथ काम किया जा सकता है। चूंकि "ट्रांसफर मनी" क्रिया नहीं है, हमें "लेनदेन" संसाधन को परिभाषित करने की आवश्यकता है जिसे सीआरयूडी के साथ काम किया जा सकता है। यहाँ एक उदाहरण है HTTP + POX में। पहला कदम एक नया खाली लेनदेन बनाने (HTTP POST विधि) है :

POST /transaction

यह एक लेनदेन आईडी देता है, उदाहरण के लिए "1234" और URL के अनुसार "/ लेनदेन / 1234"। ध्यान दें कि इस POST को कई बार फायर करने से कई ID के साथ एक ही लेन-देन नहीं होगा और "लंबित" स्थिति से भी बचा जा सकता है। इसके अलावा, POST हमेशा बेकार (एक REST की आवश्यकता) नहीं हो सकता है, इसलिए यह आमतौर पर POST में डेटा को कम करने के लिए अच्छा अभ्यास है।

आप लेन-देन आईडी की पीढ़ी को ग्राहक तक छोड़ सकते हैं। इस स्थिति में, आप लेन-देन "1234" बनाने के लिए POST / लेनदेन / 1234 करेंगे और यदि यह पहले से मौजूद है तो सर्वर एक त्रुटि लौटाएगा। त्रुटि प्रतिक्रिया में, सर्वर एक उपयुक्त URL के साथ वर्तमान में अप्रयुक्त आईडी लौटा सकता है। जीईटी विधि के साथ नई आईडी के लिए सर्वर को क्वेरी करना एक अच्छा विचार नहीं है, क्योंकि जीईटी को सर्वर स्थिति को कभी भी बदलना नहीं चाहिए, और नई आईडी बनाने / संग्रहीत करने से सर्वर स्थिति बदल जाएगी।

आगे, हम अद्यतन (PUT HTTP विधि) सभी डेटा के साथ लेन-देन, परोक्ष यह करने से:

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

यदि ID "1234" के साथ लेनदेन पहले PUT हो चुका है, तो सर्वर एक त्रुटि प्रतिक्रिया देता है, अन्यथा पूरा लेनदेन देखने के लिए एक ओके प्रतिक्रिया और एक URL।

नायब: / अकाउंट / जॉन में, "जॉन" वास्तव में जॉन का यूनिक अकाउंट नंबर होना चाहिए।


4
CRUD के साथ REST की बराबरी करना एक गंभीर गलती है। POST का मतलब सृजन नहीं है।

12
गंभीर गलती? मुझे पता है कि PUT और POST के बीच अंतर हैं, लेकिन CRUD के लिए एक ढीला मानचित्रण है। "सच में?"
टेड जॉनसन

3
हां गंभीरतापूर्वक। CRUD डेटा संग्रहण को संरचित करने का एक तरीका है; REST अनुप्रयोग डेटा प्रवाह को संरचित करने का एक तरीका है। आप REST पर CRUD कर सकते हैं, लेकिन आप CRUD पर REST नहीं कर सकते। वे समकक्ष नहीं हैं।
जॉन वाट्स

20

महान सवाल, REST को ज्यादातर डेटाबेस-जैसे उदाहरणों के साथ समझाया जाता है, जहां कुछ संग्रहीत, अद्यतन, पुनर्प्राप्त, हटा दिया जाता है। इस तरह के कुछ उदाहरण हैं, जहां सर्वर को डेटा को किसी तरह से संसाधित करना है। मुझे नहीं लगता कि रॉय फील्डिंग ने अपनी थीसिस में किसी को भी शामिल किया, जो सब के बाद http पर आधारित था।

लेकिन वह राज्य मशीन के रूप में "प्रतिनिधित्ववादी राज्य हस्तांतरण" के बारे में बात करता है, अगले राज्य में लिंक के साथ। इस तरह, दस्तावेज़ (अभ्यावेदन) क्लाइंट स्टेट का ट्रैक रखते हैं, बजाय सर्वर के इसे करने के लिए। इस तरह, कोई भी क्लाइंट स्टेट नहीं है, केवल इस बात पर ध्यान दें कि आप किस लिंक पर हैं।

मैं इस बारे में सोच रहा था, और यह मुझे उचित लगता है कि सर्वर को आपके लिए कुछ संसाधित करने के लिए, जब आप अपलोड करते हैं, तो सर्वर स्वचालित रूप से संबंधित संसाधन बनाएगा, और आपको उन्हें लिंक देगा (वास्तव में, यह नहीं होगा 'स्वचालित रूप से उन्हें बनाने की आवश्यकता नहीं है: यह सिर्फ आपको लिंक बता सकता है, और यह केवल उन्हें बनाता है जब और यदि आप उनका अनुसरण करते हैं - आलसी निर्माण)। और आपको नए संबंधित संसाधन बनाने के लिए लिंक भी देता है - एक संबंधित संसाधन में एक ही URI होता है, लेकिन लंबा होता है (एक प्रत्यय जोड़ता है)। उदाहरण के लिए:

  1. आप सभी जानकारी के साथ लेन-देन की अवधारणा का प्रतिनिधित्व ( POST ) अपलोड करते हैं। यह एक आरपीसी कॉल की तरह दिखता है, लेकिन यह वास्तव में "प्रस्तावित लेनदेन संसाधन" बना रहा है। उदा URI: /transaction Glitches के कारण ऐसे कई संसाधन बनेंगे, जिनमें से प्रत्येक एक अलग URI होगा।
  2. सर्वर की प्रतिक्रिया में निर्मित संसाधन का यूआरआई बताता है, इसका प्रतिनिधित्व - इसमें एक नया "प्रतिबद्ध लेनदेन संसाधन" के संबंधित संसाधन बनाने के लिए लिंक ( यूआरआई ) शामिल है अन्य संबंधित संसाधन प्रस्तावित लेनदेन को हटाने के लिए लिंक हैं। ये राज्य-मशीन में स्थित राज्य हैं, जिनका ग्राहक अनुसरण कर सकता है। तार्किक रूप से, ये उस संसाधन का हिस्सा होते हैं जो सर्वर पर निर्मित ग्राहक द्वारा दी गई जानकारी से परे होता है। जैसे यूआरआई: /transaction/1234/proposed, /transaction/1234/committed
  3. आप "प्रतिबद्ध लेन-देन संसाधन" बनाने के लिए लिंक पर पोस्ट करते हैं , जो उस संसाधन को बनाता है, सर्वर की स्थिति (दो खातों की शेष राशि) को बदलकर **। इसकी प्रकृति से, यह संसाधन केवल एक बार बनाया जा सकता है, और इसे अपडेट नहीं किया जा सकता है। इसलिए, कई लेनदेन करने वाले ग्लिच नहीं हो सकते हैं।
  4. आप उन दो संसाधनों को प्राप्त कर सकते हैं, यह देखने के लिए कि उनका राज्य क्या है। यह मानते हुए कि एक POST अन्य संसाधनों को बदल सकता है, अब प्रस्ताव को "प्रतिबद्ध" (या शायद, बिल्कुल उपलब्ध नहीं) के रूप में चिह्नित किया जाएगा।

यह वेबपृष्ठों के संचालन के समान है, अंतिम वेबपृष्ठ के साथ यह कहते हुए कि "क्या आप सुनिश्चित हैं कि आप ऐसा करना चाहते हैं?" वह अंतिम वेबपेज स्वयं लेन-देन की स्थिति का एक प्रतिनिधित्व है, जिसमें अगले राज्य में जाने के लिए एक लिंक शामिल है। सिर्फ वित्तीय लेनदेन नहीं; भी (उदाहरण) पूर्वावलोकन तो wikipedia पर। मुझे लगता है कि REST में अंतर यह है कि राज्यों के अनुक्रम में प्रत्येक चरण का एक स्पष्ट नाम (इसका URI) है।

वास्तविक जीवन के लेन-देन / बिक्री में, लेनदेन के विभिन्न चरणों (प्रस्ताव, खरीद आदेश, रसीद आदि) के लिए अक्सर अलग-अलग भौतिक दस्तावेज होते हैं। घर खरीदने के लिए और भी अधिक, निपटान आदि के साथ।

OTOH यह महसूस करता है कि मुझे शब्दार्थ के साथ खेलना पसंद है; मैं क्रियाओं को संज्ञा में बदलने के नाममात्र के साथ असहज हूं, इसे "RESTful" बनाने के लिए, क्योंकि यह क्रिया (RPC कॉल) के बजाय संज्ञा (URI) का उपयोग करता है। अर्थात क्रिया के बजाय संज्ञा "प्रतिबद्ध लेनदेन संसाधन" "इस लेनदेन को प्रतिबद्ध करें"। मुझे लगता है कि नाममात्रीकरण का एक फायदा यह है कि आप संसाधन को नाम से संदर्भित कर सकते हैं, इसके बजाय इसे किसी अन्य तरीके से निर्दिष्ट करने की आवश्यकता है (जैसे कि सत्र राज्य बनाए रखना, इसलिए आप जानते हैं कि "यह" लेनदेन क्या है ...)

लेकिन महत्वपूर्ण सवाल यह है: इस दृष्टिकोण के क्या लाभ हैं? यानी किस तरह से यह REST- शैली RPC- शैली से बेहतर है? क्या ऐसी तकनीक जो वेबपेजों के लिए बहुत अच्छी है, प्रसंस्करण की जानकारी के लिए भी उपयोगी है, स्टोर से परे / पुनः प्राप्त / अद्यतन / हटाएं? मुझे लगता है कि REST का मुख्य लाभ स्केलेबिलिटी है; इसका एक पहलू ग्राहक की स्थिति को स्पष्ट रूप से बनाए रखने की आवश्यकता नहीं है (लेकिन इसे संसाधन के यूआरआई में निहित है, और अगले राज्यों को इसके प्रतिनिधित्व में लिंक के रूप में)। उस लिहाज से यह मदद करता है। शायद यह लेयरिंग / पाइपलाइनिंग में भी मदद करता है? OTOH केवल एक उपयोगकर्ता अपने विशिष्ट लेन-देन को देखेगा, इसलिए इसे कैशिंग करने में कोई लाभ नहीं है ताकि अन्य इसे पढ़ सकें, http के लिए बड़ी जीत।


क्या आप बता सकते हैं कि कैसे "क्लाइंट पर राज्य रखने की आवश्यकता नहीं है" स्केलेबिलिटी में मदद करता है? किस तरह का स्केलेबिलिटी? किस अर्थ में स्केलेबिलिटी?
jhegedus

11

यदि आप यहां चर्चा को संक्षेप में बताने के लिए खड़े हैं, तो यह बहुत स्पष्ट है कि REST कई एपीआई के लिए उपयुक्त नहीं है, खासकर जब क्लाइंट-सर्वर इंटरैक्शन स्वाभाविक रूप से स्टेटफुल है, क्योंकि यह गैर-तुच्छ लेनदेन के साथ है। क्लाइंट और सर्वर दोनों के लिए सुझाए गए सभी हुप्स के माध्यम से कूदते हैं, ताकि समस्या को ठीक न करने वाले कुछ सिद्धांत का पालन किया जा सके? एक बेहतर सिद्धांत यह है कि ग्राहक को आवेदन के साथ सबसे आसान, सबसे प्राकृतिक, उत्पादक तरीका दिया जाए।

सारांश में, यदि आप वास्तव में अपने आवेदन में बहुत सारे लेनदेन (प्रकार, उदाहरण नहीं) कर रहे हैं, तो आपको वास्तव में एक RESTful API नहीं बनाना चाहिए।


9
सही, लेकिन वितरित सूक्ष्म सेवा वास्तुकला के मामले में एक विकल्प क्या होना चाहिए?
विटामन

11

मैं 10 साल से इस विषय से दूर हूं। वापस आ रहा है, मैं विश्वास नहीं कर सकता कि जब आप गूगल रेस्ट + विश्वसनीय होते हैं, तो आप उस विज्ञान को विज्ञान के रूप में समझ लेते हैं, जिसे आप मिटा देते हैं। भ्रम मिथकीय है।

मैं इस व्यापक प्रश्न को तीन भागों में बाँटूँगा:

  • डाउनस्ट्रीम सेवाएं। आपके द्वारा विकसित की जाने वाली किसी भी वेब सेवा में आपके द्वारा उपयोग की जाने वाली डाउनस्ट्रीम सेवाएं होंगी, और जिनके लेन-देन के सिंटैक्स के पास आपके पास अनुसरण करने के अलावा कोई विकल्प नहीं होगा। आपको अपनी सेवा के उपयोगकर्ताओं से यह सब छिपाने की कोशिश करनी चाहिए, और सुनिश्चित करें कि आपके ऑपरेशन के सभी हिस्से एक समूह के रूप में सफल हों या विफल हों, फिर इस परिणाम को अपने उपयोगकर्ताओं को लौटाएं।
  • आपकी सेवाएं ग्राहक वेब-सेवा कॉल के लिए अस्पष्ट परिणाम चाहते हैं, और POST, PUT या DELETE अनुरोध करने के सामान्य तरीके सीधे तौर पर मुझे भारी संसाधनों के रूप में अनुरोध करते हैं, और मुझे यह निश्चितता प्रदान करने का तरीका, एक गरीब के रूप में और आसानी से सुधार हुआ है। यदि आप विश्वसनीयता के बारे में परवाह करते हैं, तो आपको कार्रवाई अनुरोधों की पहचान करने की आवश्यकता है। यह आईडी क्लाइंट पर बनाई गई एक गाइड हो सकती है, या सर्वर पर रिलेशनल डीबी से बीज का मूल्य हो सकता है, इससे कोई फर्क नहीं पड़ता। आईडी जनरेट किए गए सर्वर के लिए, कार्रवाई की आईडी का आदान-प्रदान करने के लिए एक 'प्रीफ़्लाइट' अनुरोध-प्रतिक्रिया का उपयोग करें। यदि यह अनुरोध विफल हो जाता है या आधा सफल होता है, तो कोई समस्या नहीं है, ग्राहक केवल अनुरोध दोहराता है। अप्रयुक्त आईडी कोई नुकसान नहीं करते हैं।

    यह महत्वपूर्ण है क्योंकि यह सभी बाद के अनुरोधों को पूरी तरह से निष्प्रभावी होने देता है, इस अर्थ में कि यदि वे n बार दोहराए जाते हैं तो वे एक ही परिणाम देते हैं और आगे कुछ भी नहीं होने देते हैं। सर्वर एक्शन आईडी के खिलाफ सभी प्रतिक्रियाओं को संग्रहीत करता है, और यदि वह समान अनुरोध देखता है, तो वह उसी प्रतिक्रिया को फिर से करता है। पैटर्न का एक पूर्ण उपचार इस Google डॉक्टर में है । डॉक्टर एक कार्यान्वयन का सुझाव देते हैं कि, मेरा मानना ​​है (!), मोटे तौर पर REST रियासतों का अनुसरण करता है। विशेषज्ञ निश्चित रूप से मुझे बताएंगे कि यह दूसरों का उल्लंघन कैसे करता है। इस पैटर्न को आपकी वेब-सेवा में किसी भी असुरक्षित कॉल के लिए उपयोगी रूप से नियोजित किया जा सकता है, चाहे इसमें डाउनस्ट्रीम लेनदेन शामिल हों या नहीं।
  • अपस्ट्रीम सेवाओं द्वारा नियंत्रित "लेनदेन" में आपकी सेवा का एकीकरण। वेब-सेवाओं के संदर्भ में, पूर्ण एसीआईडी ​​लेनदेन को आमतौर पर प्रयास के लायक नहीं माना जाता है, लेकिन आप अपनी पुष्टि प्रतिक्रिया में लिंक रद्द और / या पुष्टि करके अपनी सेवा के उपभोक्ताओं की मदद कर सकते हैं, और इस प्रकार मुआवजे के द्वारा लेनदेन प्राप्त कर सकते हैं ।

आपकी आवश्यकता एक मौलिक है। लोगों को यह न बताएं कि आपका समाधान कोषेर नहीं है। कितनी अच्छी तरह, और कैसे बस के प्रकाश में अपने आर्किटेक्चर का न्याय करें, वे आपकी समस्या का समाधान करते हैं।


9

आपको अपने "लेनदेन आईडी" प्रकार के tx प्रबंधन को रोल करना होगा। तो यह 4 कॉल होगा:

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)

आपको DB (यदि लोड संतुलित है) या मेमोरी में या इसके बाद कमिटमेंट, रोलबैक, टाइमआउट को संभालना है, तो आपको एक्शन को स्टोर करना होगा।

वास्तव में पार्क में एक उत्साहपूर्ण दिन नहीं है।


4
मुझे नहीं लगता कि यह एक विशेष रूप से अच्छा चित्रण है। आपको केवल दो चरणों की आवश्यकता है: लेन-देन बनाएं ("लंबित" स्थिति में एक लेन-देन बनाता है) और प्रतिबद्ध लेनदेन (यदि काम नहीं करता है, और प्रतिबद्ध या लुढ़का हुआ राज्य के लिए संसाधन को स्थानांतरित करता है)।
जॉन वाट

2

मुझे लगता है कि इस मामले में यह इस स्थिति में REST के शुद्ध सिद्धांत को तोड़ने के लिए पूरी तरह से स्वीकार्य है। किसी भी मामले में, मुझे नहीं लगता कि वास्तव में REST में ऐसा कुछ है जो कहता है कि आप व्यवसाय के मामलों में निर्भर वस्तुओं को छू नहीं सकते हैं जिनकी आवश्यकता है।

मुझे वास्तव में लगता है कि यह अतिरिक्त हूप के लायक नहीं है जिसे आप एक कस्टम लेनदेन प्रबंधक बनाने के लिए कूदेंगे, जब आप इसे करने के लिए डेटाबेस का लाभ उठा सकते हैं।


2

सबसे पहले पैसा ट्रांसफर करना ऐसा कुछ भी नहीं है जिसे आप किसी सिंगल रिसोर्स कॉल में नहीं कर सकते। आप जो कार्रवाई करना चाहते हैं वह पैसा भेज रहा है। तो आप भेजने वाले के खाते में एक मनी ट्रांसफर संसाधन जोड़ दें।

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

किया हुआ। आपको यह जानने की आवश्यकता नहीं है कि यह एक ऐसा लेनदेन है जो परमाणु होना चाहिए आदि। आप सिर्फ पैसा उर्फ ​​स्थानांतरित करते हैं। A से B तक पैसे भेजें।


लेकिन यहां दुर्लभ मामलों के लिए एक सामान्य समाधान:

यदि आप परिभाषित संदर्भ में कई संसाधनों को शामिल करते हुए कुछ बहुत जटिल करना चाहते हैं, तो बहुत सारे प्रतिबंध हैं जो वास्तव में क्या बनाम क्यों (व्यापार बनाम कार्यान्वयन ज्ञान) को पार करते हैं, आपको राज्य को स्थानांतरित करने की आवश्यकता है। चूंकि REST आपको स्टेटलेस होना चाहिए, क्योंकि क्लाइंट को राज्य को स्थानांतरित करने की आवश्यकता होती है।

यदि आप राज्य को स्थानांतरित करते हैं तो आपको क्लाइंट से अंदर की जानकारी छिपाने की आवश्यकता है। ग्राहक को केवल कार्यान्वयन के लिए आवश्यक आंतरिक जानकारी का पता नहीं होना चाहिए, लेकिन व्यापार के संदर्भ में जानकारी को प्रासंगिक नहीं रखता है। यदि उन सूचनाओं का कोई व्यावसायिक मूल्य नहीं है, तो राज्य को एन्क्रिप्ट किया जाना चाहिए और टोकन, पास या कुछ जैसे रूपक का उपयोग करने की आवश्यकता है।

इस तरह से कोई भी आंतरिक स्थिति को चारों ओर से गुजर सकता है और एन्क्रिप्शन का उपयोग कर सकता है और सिस्टम पर हस्ताक्षर करना अभी भी सुरक्षित और मजबूत हो सकता है। ग्राहक के लिए सही अमूर्तता क्यों वह राज्य की जानकारी के आसपास से गुजरता है कुछ ऐसा है जो डिजाइन और वास्तुकला पर निर्भर है।


वास्तविक समाधान:

याद रखें कि REST HTTP पर बात कर रहा है और HTTP कुकीज़ के उपयोग की अवधारणा के साथ आता है। उन कुकीज़ को अक्सर भुला दिया जाता है जब लोग REST API और वर्कफ़्लो और कई संसाधनों या अनुरोधों को लेकर बातचीत के बारे में बात करते हैं।

याद रखें कि HTTP कुकीज़ के बारे में विकिपीडिया में क्या लिखा है:

वेबसाइटों को स्टेटफ़ुल जानकारी (जैसे कि शॉपिंग कार्ट में आइटम) या उपयोगकर्ता की ब्राउज़िंग गतिविधि (जिसमें विशेष बटन पर क्लिक करना, लॉग इन करना या रिकॉर्डिंग करना शामिल है) को रिकॉर्ड करने के लिए वेबसाइटों के लिए कुकीज़ को एक विश्वसनीय तंत्र के रूप में डिज़ाइन किया गया था। महीने या साल पहले)।

इसलिए मूल रूप से यदि आपको राज्य से गुजरने की आवश्यकता है, तो कुकी का उपयोग करें। यह बिल्कुल उसी कारण के लिए डिज़ाइन किया गया है, यह HTTP है और इसलिए यह डिज़ाइन द्वारा REST के लिए संगत है :)।


बेहतर समाधान:

यदि आप एक क्लाइंट के बारे में बात करते हैं जो एक वर्कफ़्लो करता है जिसमें आप आमतौर पर प्रोटोकॉल के बारे में बात करते हैं। प्रोटोकॉल के हर रूप में प्रत्येक संभावित कदम के लिए पूर्व शर्त का एक सेट के साथ आता है जैसे कि बी करने से पहले चरण ए का प्रदर्शन करें।

यह स्वाभाविक है लेकिन ग्राहकों के लिए प्रोटोकॉल को उजागर करना सब कुछ अधिक जटिल बनाता है। इससे बचने के लिए हमें लगता है कि हम क्या करते हैं जब हमें वास्तविक दुनिया में जटिल बातचीत और चीजों को करना पड़ता है ...। हम एक एजेंट का उपयोग करते हैं।

एजेंट रूपक का उपयोग करके आप एक संसाधन प्रदान कर सकते हैं जो आपके लिए सभी आवश्यक कदमों का प्रदर्शन कर सकता है और इसकी सूची में काम कर रहे वास्तविक असाइनमेंट / निर्देशों को संग्रहीत कर सकता है (इसलिए हम एजेंट या एक 'एजेंसी' पर POST का उपयोग कर सकते हैं)।

एक जटिल उदाहरण:

एक घर खरीदना:

आपको अपनी विश्वसनीयता साबित करने की आवश्यकता है (जैसे कि आपकी पुलिस रिकॉर्ड प्रविष्टियां प्रदान करना), आपको वित्तीय विवरण सुनिश्चित करने की आवश्यकता है, आपको एक वकील का उपयोग करके वास्तविक घर खरीदने की आवश्यकता है और एक विश्वसनीय तीसरे पक्ष द्वारा धनराशि का भंडारण किया जाता है, सत्यापित करें कि घर अब आपका है और अपने कर रिकॉर्ड आदि में खरीदारी का सामान जोड़ें (बस एक उदाहरण के रूप में, कुछ कदम गलत हो सकते हैं या जो भी हो)।

इन चरणों को पूरा होने में कई दिन लग सकते हैं, कुछ समानांतर आदि में किए जा सकते हैं।

ऐसा करने के लिए, आप एजेंट को घर खरीदने का काम देते हैं जैसे:

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

किया हुआ। एजेंसी आपको एक संदर्भ वापस भेजती है जिसका उपयोग आप इस नौकरी की स्थिति को देखने और ट्रैक करने के लिए कर सकते हैं और बाकी एजेंसी के एजेंटों द्वारा स्वचालित रूप से किया जाता है।

उदाहरण के लिए बग ट्रैकर के बारे में सोचें। मूल रूप से आप बग की रिपोर्ट करते हैं और व्हाट्स आइडी को जांचने के लिए बग आईडी का उपयोग कर सकते हैं। आप इस संसाधन के परिवर्तनों को सुनने के लिए किसी सेवा का उपयोग भी कर सकते हैं। मिशन पूरा हुआ।


1

आपको REST में सर्वर साइड लेनदेन का उपयोग नहीं करना चाहिए।

अन्य विरोधाभासों में से एक:

राज्यविहीन

क्लाइंट-सर्वर संचार आगे ग्राहक अनुरोधों के बीच सर्वर पर संग्रहीत नहीं किया जा रहा द्वारा विवश है। किसी भी ग्राहक के प्रत्येक अनुरोध में अनुरोध को पूरा करने के लिए आवश्यक सभी जानकारी होती है, और ग्राहक में कोई भी सत्र स्थिति होती है।

एकमात्र तरीका यह है कि लेन-देन फिर से लॉग इन करें और इसे क्लाइंट स्थिति में डालें। अनुरोधों के साथ क्लाइंट रीडो लॉग भेजता है और सर्वर लेनदेन को कम करता है और

  1. लेन-देन वापस करता है, लेकिन एक नया लेनदेन फिर से लॉग (एक कदम आगे) प्रदान करता है
  2. या अंत में लेन-देन पूरा करें।

लेकिन शायद सर्वर सत्र आधारित तकनीक का उपयोग करना सरल है जो सर्वर साइड लेनदेन का समर्थन करता है।


उद्धरण विकिपीडिया REST प्रविष्टि से है। क्या यह वास्तविक स्रोत है या विकिपीडिया इसे कहीं से मिला है? ग्राहक संदर्भ क्या है और सर्वर संदर्भ क्या है?
bbsimonbb

1

मेरा मानना ​​है कि यह सुनिश्चित करने के लिए क्लाइंट पर एक विशिष्ट पहचानकर्ता का उपयोग करने का मामला होगा ताकि यह सुनिश्चित हो सके कि एपीआई द्वारा सेव किए गए डुप्लिकेट में कनेक्शन हिचकी नहीं है।

मुझे लगता है कि ट्रांसफर ऑब्जेक्ट के साथ एक GUID फ़ील्ड जनरेट करने वाले ग्राहक का उपयोग करना और यह सुनिश्चित करना कि उसी GUID को फिर से नहीं लगाया गया था, बैंक हस्तांतरण मामले का एक सरल समाधान होगा।

अधिक जटिल परिदृश्यों के बारे में नहीं जानते हैं, जैसे कई एयरलाइन टिकट बुकिंग या माइक्रो आर्किटेक्चर।

मुझे इस विषय के बारे में एक पेपर मिला, जिसमें रेस्टफुल सेवाओं में लेनदेन की असमानता से निपटने के अनुभवों से संबंधित था


0

साधारण मामले में (वितरित संसाधनों के बिना), आप लेनदेन को एक संसाधन के रूप में मान सकते हैं, जहाँ इसे बनाने का कार्य अंतिम उद्देश्य को प्राप्त करता है।

तो, के बीच हस्तांतरण करने के लिए <url-base>/account/aऔर <url-base>/account/b, आप के लिए निम्नलिखित पोस्ट कर सकता <url-base>/transfer

<हस्तांतरण>
    <यूआरएल आधार> <से> / खाता / a <से />
    <के लिए> <यूआरएल आधार> / खाता / b </ करने के लिए>
    <राशि> 50 </ राशि>
</ स्थानांतरण>

यह एक नया स्थानांतरण संसाधन बनाएगा और स्थानांतरण का नया यूआरएल लौटाएगा - उदाहरण के लिए <url-base>/transfer/256

सफल पोस्ट के क्षण में, फिर, सर्वर पर 'वास्तविक' लेनदेन किया जाता है, और एक खाते से निकाली गई राशि और दूसरे में जोड़ दी जाती है।

यह, हालांकि, एक वितरित लेनदेन को कवर नहीं करता है (यदि, कहते हैं कि 'ए' को एक सेवा के पीछे एक बैंक में आयोजित किया जाता है, और 'बी' को किसी अन्य सेवा के पीछे दूसरे बैंक में आयोजित किया जाता है) - इसके अलावा अन्य कहने के लिए "सभी वाक्यांशों को आज़माएं उन तरीकों से संचालन जो वितरित लेनदेन की आवश्यकता नहीं है "।


2
यदि आप "सभी कार्यों को उन तरीकों से वाक्यांशित नहीं कर सकते हैं जिन्हें वितरित लेनदेन की आवश्यकता नहीं है", तो आपको वास्तव में दो चरण की प्रतिबद्धताओं की आवश्यकता है। REST पर दो चरण प्रतिबद्ध लागू करने के लिए मुझे जो सबसे अच्छा विचार मिल सकता है वह है rest.blueoxen.net/cgi-bin/wiki.pl?TwoPhaseCommit , जो महत्वपूर्ण रूप से URL नामस्थान को गड़बड़ नहीं करता है और एक दो चरण के लिए स्तरित होने की अनुमति देता है। स्वच्छ REST शब्दार्थ।
फसमल

3
इस सुझाव के साथ दूसरी समस्या यह है कि, यदि कोई कैश हिचकी और दो बार POST करता है, तो आपको दो स्थानान्तरण मिलते हैं।
जॉन वाट

सही है, जिस स्थिति में आपको दो चरण की प्रक्रिया की आवश्यकता होगी - एक अद्वितीय URL के साथ "ट्रांसफ़र" संसाधन बनाएं फिर ट्रांसफर विवरण को कमिट के हिस्से के रूप में जोड़ें (दो भागों जैसा कि अन्य उत्तरों में उल्लेख किया गया है)। बेशक, यह तब "लेनदेन" संसाधन बनाने के रूप में फिर से शुरू किया जा सकता है, फिर इसमें "हस्तांतरण" ऑपरेशन को जोड़ा जा सकता है।
चरण 23

-3

मुझे लगता है कि आप URL / संसाधन में TAN शामिल कर सकते हैं:

  1. आईडी प्राप्त करने के लिए PUT / लेनदेन (उदाहरण के लिए "1")
  2. [PUT, GET, POST, जो भी हो] / 1 / खाता / बॉब
  3. [PUT, GET, POST, जो भी हो] / 1 / खाता / बिल
  4. DELETE / ID 1 के साथ लेन-देन

एक विचार है।


मैं इस दृष्टिकोण के साथ दो समस्याएं देखता हूं: 1) इसका मतलब है कि आप एक लेनदेन के बाहर एक संसाधन तक नहीं पहुंच सकते हैं (हालांकि शायद यह कोई बड़ी बात नहीं है)। 2) अब तक किसी भी उत्तर ने इस तथ्य को नहीं छुआ है कि सर्वर अब स्टेटलेस नहीं है, हालांकि मुझे संदेह है कि इस बारे में कुछ नहीं किया जा सकता है।
गिली

खैर, / 1 / खाता / बॉब और / खाता / बॉब केवल दो अलग-अलग संसाधन हैं। :) और आरई: स्टेटलेस, यह तात्पर्य है कि संसाधन हमेशा उपलब्ध है और पिछले अनुरोध पर निर्भर नहीं है। चूंकि आपने लेनदेन के लिए कहा था, हां ऐसा नहीं है। लेकिन फिर, आप लेनदेन चाहते थे।
जब तक

1
यदि किसी क्लाइंट को यूआरआई को इकट्ठा करना है, तो आपका एपीआई रेस्टफुल नहीं है।
aehlke

1
मैं तुम लोगों को नहीं समझ सकता, सच में! यदि आप किसी लेन-देन को एक संसाधन के रूप में मानते हैं (जैसे ऊपर दिए गए उदाहरण में) तो आप केवल शास्त्रीय अर्थों में लेन-देन का इलाज करना बंद कर देते हैं और इसे "उचित रीस्ट रास्ते" में उपयोग करते हैं जो प्रोग्रामिंग लेनदेन प्रक्रियाओं को और सरल बनाता है। आप उदाहरण के लिए वितरित सर्वर-साइड वातावरण में विस्थापन के आसपास जाने के लिए अपनी प्रतिक्रियाओं में लेनदेन के लिए एक href शामिल कर सकते हैं, यह अभी भी स्टेटलेस है (यह सिर्फ एक संसाधन है, है ना?) और आप वैसे भी वास्तविक लेनदेन तंत्र को लागू कर सकते हैं? चाहते हैं (क्या होगा अगर आपके पास एक डीबी नहीं है?)
माथियास ह्रीनिज़क

1
एक तरीका या दूसरा यदि आप बस SQL ​​/ SOAP सोचना बंद कर दें और HTTP सोचना शुरू करें (जैसे ब्राउज़र करता है) सब कुछ सरल हो जाता है
Matthias Hryniszak
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.