क्या एनेमिक डोमेन मॉडल को प्रोत्साहित करने के लिए RESTful API का उपयोग किया जाता है?


34

मैं एक ऐसी परियोजना पर काम कर रहा हूं जिसमें हम डोमेन-संचालित डिज़ाइन और REST दोनों को एक सेवा-उन्मुख वास्तुकला में लागू करने का प्रयास कर रहे हैं। हम 100% REST अनुपालन की चिंता नहीं कर रहे हैं; यह कहना बेहतर होगा कि हम संसाधन-उन्मुख HTTP APIs बनाने की कोशिश कर रहे हैं (~ रिचर्डसन के REST परिपक्वता अवधि के स्तर 2 )। फिर भी, हम HTTP अनुरोधों के RPC- शैली के उपयोग से दूर रहने की कोशिश कर रहे हैं, अर्थात हम उदाहरण के लिए, उपयोग करने के बजाय RFC2616 के अनुसार अपने HTTP क्रियाओं को लागू करने का प्रयास POSTकरते हैं IsPostalAddressValid(...)

हालाँकि, इस पर एक जोर डोमेन-संचालित डिज़ाइन को लागू करने के हमारे प्रयास की कीमत पर लगता है। केवल के साथ GET, POST, PUT, DELETEऔर कुछ अन्य शायद ही कभी इस्तेमाल किया तरीकों, हम cruddy सेवाओं का निर्माण करते हैं, और cruddy सेवाओं कमजोर डोमेन मॉडल हो जाते हैं।

POST: डेटा प्राप्त करें, इसे मान्य करें, इसे डेटा पर डंप करें। GET: डेटा पुनर्प्राप्त करें, इसे वापस लौटाएं। वहां कोई वास्तविक व्यापार तर्क नहीं है। हम सेवाओं के बीच संदेशों (घटनाओं) का भी उपयोग करते हैं, और यह मुझे लगता है कि अधिकांश व्यापारिक तर्क समाप्त हो जाते हैं।

क्या REST और DDD कुछ स्तर पर तनाव में हैं? (या क्या मैं यहां कुछ गलत समझ रहा हूं? क्या हम शायद कुछ और गलत कर रहे हैं?) क्या आरपीसी-स्टाइल HTTP कॉल से बचते हुए सेवा उन्मुख वास्तुकला में एक मजबूत डोमेन मॉडल बनाना संभव है?


1
POST को जानबूझकर "जानबूझकर अस्पष्ट;" POST का परिणाम कार्यान्वयन-विशिष्ट है। आपको ट्विटर और अन्य एपीआई डिज़ाइनर क्या करने से रोकते हैं, और अपने एपीआई की गैर-सीआरयूडी हिस्से में प्रत्येक पोस्ट विधि को अपनी विशिष्ट आवश्यकताओं के अनुसार परिभाषित करते हैं?
रॉबर्ट हार्वे

@RobertHarvey हमने POST एक निर्माण के रूप में लिया है। मानक को फिर से देखते हुए , शायद यह अति सरलीकृत है। उदाहरण के लिए, क्या आपको लगता है कि POST करने के लिए IsPostalAddressValid(...)"डेटा का एक ब्लॉक प्रदान करना, जैसे कि फॉर्म सबमिट करने, डेटा से निपटने की प्रक्रिया के परिणामस्वरूप" फिट होगा?
काजर

ऐसा इसलिए है क्योंकि वहाँ कोई सृजन क्रिया है (और उस मामले के लिए कोई अद्यतन क्रिया नहीं है)। मैं यह सुनिश्चित करता हूं कि वे क्रियाएं मानक से गायब हैं (जो भी कारण हो), यही वजह है कि आपको "सब कुछ" के लिए POST का सह-चयन करना होगा। इस मामले में आपकी "डेटा हैंडलिंग प्रक्रिया", वह प्रक्रिया है जो डाक पते की जांच करती है, और उस विश्लेषण के परिणाम के अनुरूप मान लौटाती है।
रॉबर्ट हार्वे

1
@RobertHarvey: मेरा मानना ​​है कि POST और PUT / PATCH केवल सृजन और अद्यतन क्रिया है जिसे आप चाहते हैं। इसे केवल अलग नाम दिया गया है, ताकि क्रिया अभी भी गैर-रेस्टफुल डिज़ाइन में कुछ समझ में आए।
रेयान

@ लीरियन: मैं आपको वह अनुदान दूंगा। मुझे बस यही लगता है कि CRUD का अर्थ है एनीमिक डेटा मॉडल। आप कुछ व्यवहार के साथ ले जा सकते हैं यदि, कहते हैं, आप एमवीसी के एम में हैं, लेकिन निश्चित रूप से विषम प्रणालियों में नहीं हैं। बाकी सब के लिए लेकिन CRUD के लिए आपको POST की जरूरत है।
रॉबर्ट हार्वे

जवाबों:


38

मार्टिन फाउलर वितरित प्रणालियों का पहला नियम: "अपनी वस्तुओं को वितरित न करें!" दूरस्थ इंटरफेस मोटे-अनाज वाले और आंतरिक इंटरफेस महीन-बारीक होने चाहिए। अक्सर समृद्ध डोमेन मॉडल केवल एक सीमित संदर्भ में लागू होता है

REST API दो अलग-अलग संदर्भों को अलग करती है जिसमें दोनों के अपने आंतरिक मॉडल होते हैं। संदर्भ "एनेमिक" ऑब्जेक्ट्स (डीटीओ) का उपयोग करके मोटे-दाने वाले इंटरफ़ेस (आरईएसटी एपीआई) के माध्यम से संवाद करते हैं।

आपके मामले में ऐसा लगता है कि आप एक सीमा पर एक संदर्भ फैलाने की कोशिश कर रहे हैं जो कि REST API है। इससे सुदूरवर्ती सुदूरवर्ती इंटरफ़ेस या एनेमिक मॉडल बन सकता है। आपके प्रोजेक्ट के आधार पर यह समस्या हो सकती है या नहीं।


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

9

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

इसे दूसरे तरीके से रखने के लिए, आपके प्रश्न को समान रूप से प्रस्तुत किया जा सकता है क्योंकि "डू 'स्मार्ट' ऑब्जेक्ट्स आरपीसी-शैली डिजाइन को प्रोत्साहित करते हैं?" यहां तक ​​कि मार्टिन फाउलर (जिन्होंने "एनीमिक डोमेन मॉडल" शब्द गढ़ा) का मानना ​​है कि नंगे डीटीओ के कुछ लाभ हैं:

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

रिचर्डसन परिपक्वता मॉडल के बारे में , आप "एनीमिक डोमेन मॉडल" के बारे में अपने आप से कभी भी बिना स्तर 3 पर पहुँच सकते हैं। याद रखें, आप कभी भी ब्राउज़र में व्यवहार को स्थानांतरित नहीं करने जा रहे हैं (जब तक कि आप अपने मॉडलों के माध्यम से कुछ जावास्क्रिप्ट को इंजेक्ट करने की योजना नहीं बनाते हैं)।

REST ज्यादातर मशीन की स्वतंत्रता के बारे में है; REST मॉडल को उस डिग्री पर लागू करें, जिसे आप संसाधनों के प्रतिनिधित्व के लिए अपने समापन बिंदु चाहते हैं, और अपने एपीआई के उपभोक्ताओं के लिए एक मानक तरीके से उन संसाधनों को आसानी से उपयोग करने और बनाए रखने में सक्षम हैं। यदि वह एनीमिक लगता है, तो ऐसा हो।

इसके अलावा देखें
मुझे और अधिक क्रियाओं की आवश्यकता है


मुझे लगता है कि निश्चित रूप से सवाल के RFC2616 पक्ष को संबोधित करता है। इस तथ्य के बारे में कि हम संसाधन-उन्मुख होने की कोशिश कर रहे हैं, अर्थात कम से कम REST के लिए रिचर्डसन परिपक्वता मॉडल में स्तर 2 प्राप्त करने की कोशिश कर रहे हैं?
काजार्क

1
मैं martinfowler.com/articles/richardsonMaturityModel.html के माध्यम से पढ़ता हूं । आप "एनीमिक डोमेन मॉडल" के बारे में अपने आप से कभी भी बिना स्तर 3 पर पहुँच सकते हैं। याद रखें, आप कभी भी ब्राउज़र में व्यवहार को स्थानांतरित नहीं करने जा रहे हैं (जब तक कि आप अपने मॉडलों के माध्यम से कुछ जावास्क्रिप्ट को इंजेक्ट करने की योजना नहीं बनाते हैं)।
रॉबर्ट हार्वे

4

REST API एक प्रकार की प्रस्तुति परत है। डोमेन मॉडल से इसका कोई लेना-देना नहीं है।

आपके द्वारा पोस्ट किया गया प्रश्न आपके भ्रम से आता है कि आपको किसी तरह एक दूसरे को अनुकूलित करने की आवश्यकता है। तुम नहीं।

आप अपने डोमेन मॉडल को अपने REST API पर उसी तरह मैप करते हैं, जिस तरह आप अपने डोमेन मॉडल को ORM के माध्यम से RDBMS में मैप करते हैं - इस मैपिंग लेयर में होना चाहिए।

डोमेन ← ORM → RDBMS
डोमेन apping REST मैपिंग → REST API


3

IMHO मुझे नहीं लगता कि वे एनीमिक डोमेन मॉडल (ADMs) को प्रोत्साहित करते हैं, लेकिन उन्हें आपको कुछ समय लेने और सोचने की आवश्यकता है।

सबसे पहले मुझे लगता है कि एडीएम की मुख्य विशेषता यह है कि उनमें कोई व्यवहार नहीं है। यह कहने के लिए नहीं है कि सिस्टम का कोई व्यवहार नहीं है, बस यह है कि यह आमतौर पर किसी प्रकार की सेवा वर्ग में है (देखें http://vimeo.com/43598193 )।

और निश्चित रूप से अगर व्यवहार एडीएम में मौजूद नहीं है, तो क्या होता है? पाठ्यक्रम का उत्तर डेटा है। और इसलिए यह नक्शा REST API के लिए कैसा है? अच्छी तरह से संभवतः संसाधन की सामग्री के लिए डेटा मैप्स, और HTTP वर्ब के लिए व्यवहार मैप्स।

इसलिए आपके पास एक समृद्ध डोमेन मॉडल बनाने के लिए आवश्यक सब कुछ है, आपको बस यह देखना होगा कि HTTP डेटा पर डोमेन संचालन के लिए कैसे क्रिया करता है, और फिर उन ऑपरेशनों को उन्हीं कक्षाओं में रखें जो आपके डेटा को एनकैप्सुलेट करते हैं।

मुझे लगता है कि जहां लोग समस्याओं में भाग लेते हैं, उनके लिए यह कठिन समय होता है कि HTTP कैसे अपने डोमेन व्यवहार के लिए मैप करता है जब व्यवहार साधारण CRUD से परे होता है, अर्थात, जब डोमेन से परे डोमेन के अन्य हिस्सों में दुष्प्रभाव होते हैं HTTP अनुरोध द्वारा संशोधित किया जा रहा संसाधन। उस समस्या को हल करने का एक तरीका डोमेन घटनाओं ( http://www.udidahan.com/2009/06/14/domain-events-salvation/ ) के साथ है।


3

यह लेख विषय से काफी संबंधित है और मेरा मानना ​​है कि आपके प्रश्न का उत्तर है।

एक मुख्य अवधारणा जो मुझे लगता है कि आपके प्रश्न का उत्तर बहुत अच्छी तरह से दिया गया है, का उल्लेख लेख से निम्नलिखित पैराग्राफ में किया गया है:

"डोमेन संचालित डिज़ाइन में REST API और डोमेन संस्थाओं में संसाधनों के बीच अंतर करना बहुत महत्वपूर्ण है। डोमेन संचालित डिज़ाइन चीजों के कार्यान्वयन पक्ष (API कार्यान्वयन सहित) पर लागू होता है, जबकि REST API में संसाधन API डिज़ाइन और अनुबंध। API संसाधन चलाते हैं। चयन अंतर्निहित डोमेन कार्यान्वयन विवरण पर निर्भर नहीं होना चाहिए। "


1

कई यथोचित सफल कार्यान्वयन मैंने इस प्रश्न का उत्तर देखा / निर्मित किया है कि कैसे वे मोटे + संज्ञा रूपक को मोटे-अनाज वाले 'व्यापार के अनुकूल ’तरीकों का उपयोग करके मिलाते हैं जो संस्थाओं पर कार्य करते हैं।

इसलिए (doomed) getName()पद्धति / सेवा के बजाय getPerson(), पहचान करें, आइडेंटिफ़ायर-टाइप / आईडी जैसी चीजों में पास होना, पूरी Personइकाई को वापस करना ।

चूंकि इस तरह के संदर्भ में व्यक्ति इकाई के व्यवहारों को पर्याप्त रूप से व्यक्त नहीं किया जा सकता है (न ही शायद उन्हें डेटा-केंद्रित संदर्भ में होना चाहिए), यह अनुरोध / प्रतिक्रिया जोड़े के लिए डेटा (बनाम ऑब्जेक्ट) मॉडल को परिभाषित करने के लिए पूरी तरह से उचित है सेवाएं।

स्वयं सेवाओं और परिभाषित क्रियाओं में कुछ डोमेन-अनुमत व्यवहार, नियंत्रण और यहां तक ​​कि संस्थाओं के लिए राज्य-संक्रमण नियम भी शामिल होंगे। उदाहरण के लिए, डोमेन-विशिष्ट तर्क होगा कि transferPerson()सेवा कॉल में क्या होता है, लेकिन इंटरफ़ेस स्वयं ही उनके आंतरिक व्यवहार को परिभाषित किए बिना इनपुट / आउटपुट संस्थाओं / डेटा को परिभाषित करेगा।

मैं उन लेखकों से असहमत हूं जो कहेंगे, उदाहरण के लिए, एक स्थानांतरण क्रिया कार्यान्वयन व्यक्ति वर्ग में होता है या एक व्यक्ति-केंद्रित सेवा से जुड़ा होता है। वास्तव में, इसके और विकल्प के लिए स्थानांतरण की विधि Person(इस सरल उदाहरण में) को बेहतर तरीके से परिभाषित किया जाएगा Carrier, जिसमें इस बात Personका भी ज्ञान नहीं हो सकता है कि हस्तांतरण के तरीके क्या हैं या हस्तांतरण भी कैसे होता है (कौन जानता है कि जेट इंजन कैसे काम करते हैं। वैसे भी)।

क्या यह Personइकाई को एनीमिक बनाता है ? मुझे ऐसा नहीं लगता।

व्यक्ति-विशेष के बारे में तर्क / तर्क हो सकते हैं जो कि उनके स्वास्थ्य की स्थिति की तरह व्यक्ति के लिए आंतरिक हैं, जिन्हें बाहरी वर्ग द्वारा परिभाषित नहीं किया जाना चाहिए।

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


अच्छे अंक --- यह वास्तव में कुछ नए परिप्रेक्ष्य लाता है जो अन्य उत्तर अभी तक नहीं थे।
काज़ार्क

0

क्या आपकी समस्या यह है कि आप अपने मॉडल को क्रियाओं के मूल समूह में बदलने की कोशिश कर रहे हैं, यथासंभव POST का उपयोग कर रहे हैं?

यह आवश्यक नहीं है - मुझे पता है कि ज्यादातर लोगों के लिए REST का मतलब POST, GET, PUT और DELETE है, लेकिन http rf का कहना है:

HTTP / 1.1 के लिए सामान्य तरीकों के सेट को नीचे परिभाषित किया गया है। यद्यपि इस सेट का विस्तार किया जा सकता है, लेकिन अलग-अलग विस्तारित क्लाइंट और सर्वर के लिए एक ही शब्दार्थ को साझा करने के लिए अतिरिक्त तरीकों को ग्रहण नहीं किया जा सकता है।

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

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

यदि आप एक पूर्ण-सुविधाएँ, जटिल मैसेजिंग प्रोटोकॉल चाहते हैं, तो निर्माण करें (यदि आप वेब पर ऐसा कर सकते हैं, तो एक कारण है कि REST इतना लोकप्रिय है), लेकिन अन्यथा REST के वास्तुशिल्प डिज़ाइन से चिपके रहने का प्रयास करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.