सारांश
CQRS / DDD में प्राधिकरण को प्रति-कमांड / क्वेरी लागू किया जाना चाहिए या नहीं?
मैं पहली बार डीडीडी CQRS पैटर्न का अधिक या कम सख्ती से उपयोग करके एक ऑनलाइन एप्लिकेशन विकसित कर रहा हूं। मैं कुछ समस्या से टकराया, जो मुझे वास्तव में अपना सिर नहीं मिला।
मैं जिस एप्लिकेशन का निर्माण कर रहा हूं, वह एक अंडरगारमेंट एप्लिकेशन है जिससे लोग लीडर बना सकते हैं, साथ ही अन्य लोगों को उन्हें देखने / संपादित करने / हटाने की अनुमति दे सकते हैं, जैसे कि कर्मचारी। एक बही के निर्माता को उस बही के उपयोग के अधिकारों को संपादित करने में सक्षम होना चाहिए जो उसने बनाया था। यहां तक कि स्वामित्व बदल सकता है। डोमेन में दो समुच्चय हैं TLedger और TUser ।
मैंने सुरक्षा, प्राधिकरण आदि से संबंधित DDD / CQRS कीवर्ड के साथ बहुत सी पोस्ट पढ़ीं, उनमें से अधिकांश ने कहा कि प्राधिकरण एक सामान्य सबडोमेन था , जब तक कि कोई एक सुरक्षा एप्लिकेशन का निर्माण नहीं कर रहा था।
इस मामले में, कोर डोमेन एक निश्चित रूप से लेनदेन, संतुलन और खातों के साथ रुचि रखने वाला एक लेखांकन डोमेन है । लेकिन उत्पादकों तक बारीक पहुंच का प्रबंधन करने में सक्षम होने की कार्यक्षमता भी आवश्यक है। मैं सोच रहा हूं कि इसे डीडीडी / सीक्यूआरएस शर्तों में कैसे डिजाइन किया जाए।
यह डीडीडी ट्यूटोरियल में उस जगह के चारों ओर बताया गया है जहां कमांड सर्वव्यापी भाषा का हिस्सा हैं। वे सार्थक हैं। वे ठोस कार्य हैं जो "वास्तविक चीज़" का प्रतिनिधित्व करते हैं।
क्योंकि उन सभी कमांड और क्वेरी वास्तविक क्रिया हैं जो उपयोगकर्ता "वास्तविक जीवन" में निष्पादित करेंगे, क्या प्राधिकरण के कार्यान्वयन को इन सभी "कमांड" और "प्रश्नों" के साथ जोड़ा जाना चाहिए? एक उपयोगकर्ता के पास उदाहरण के लिए TLedger.addTransaction () लेकिन नहीं TLedger.removeTransaction () निष्पादित करने के लिए प्राधिकरण होगा। या, किसी उपयोगकर्ता को "getSummaries ()" क्वेरी निष्पादित करने की अनुमति होगी, लेकिन "getTransactions ()" नहीं।
एक त्रि-आयामी मानचित्रण, उपयोगकर्ता-बही-आदेश या उपयोगकर्ता-बही-खाता के रूप में मौजूद होगा जिससे अभिगम अधिकार निर्धारित किया जा सके।
या, डिकोड किए गए तरीके से, "अनुमतियाँ" नाम एक उपयोगकर्ता के लिए पंजीकृत किया जाएगा। अनुमतियाँ जो तब विशिष्ट आदेशों के लिए मैप की जाएंगी। उदाहरण के लिए, "ManageTransactions" की अनुमति उपयोगकर्ता को "AddTransaction ()", "RemoveTransaction ()", आदि निष्पादित करने की अनुमति देगा।
अनुमतियाँ मैपिंग उपयोगकर्ता -> खाता बही -> आदेश / क्वेरी
अनुमतियाँ मैपिंग उपयोगकर्ता -> खाता बही -> अनुमति -> आदेश / क्वेरी
यह सवाल का पहला हिस्सा है। या संक्षेप में, CQRS / DDD में प्राधिकरण को प्रति-आदेश या प्रति-क्वेरी को लागू किया जाना चाहिए? या, क्या प्राधिकरण को आदेशों से अलग कर दिया जाना चाहिए?
दूसरे, अनुमति के आधार पर प्राधिकरण के विषय में। एक उपयोगकर्ता को अपने लेजर पर अनुमतियों का प्रबंधन करने में सक्षम होना चाहिए या लेजर पर उसे प्रबंधित करने की अनुमति दी जानी चाहिए।
- प्राधिकरण प्रबंधन आदेश लेजर में होता है
मैंने लेज़र एग्रीगेट में ईवेंट्स / कमांड्स / हैंडलर को जोड़ने का विचार किया , जैसे कि अनुदानप्राप्ति (), रिवोकपर्मिशन (), आदि। इस मामले में, उन नियमों को लागू करना कमांड हैंडलर में होगा। लेकिन इसके लिए सभी कमांड्स को उस कमांड को जारी करने वाले यूजर की आईडी को शामिल करना होगा। तब मैं TLedger में जांच करूँगा कि क्या उस उपयोगकर्ता के लिए उस आदेश को निष्पादित करने के लिए अनुमति मौजूद है।
उदाहरण के लिए :
class TLedger{
function addTransactionCmdHandler(cmd){
if (!this.permissions.exist(user, 'addTransaction')
throw new Error('Not Authorized');
}
}
- प्राधिकरण प्रबंधन उपयोगकर्ता में आदेश देता है
अन्य तरीकों से TUser में अनुमतियों को शामिल किया जाएगा। TUser के पास अनुमतियों का एक सेट होगा। तब, TLedger कमांड संचालकों में, मैं उपयोगकर्ता को पुनः प्राप्त करूंगा और जांच करूंगा कि उसके पास कमांड निष्पादित करने की अनुमति है या नहीं। लेकिन इसके लिए मुझे हर TLedger कमांड के लिए TUser एग्रीगेट लाना होगा।
class TAddTransactionCmdHandler(cmd) {
this.userRepository.find(cmd.userId)
.then(function(user){
if (!user.can(cmd)){
throw new Error('Not authorized');
}
return this.ledgerRepository.find(cmd.ledgerId);
})
.then(function(ledger){
ledger.addTransaction(cmd);
})
}
- सेवा के साथ एक और डोमेन
एक और संभावना एक और प्राधिकरण डोमेन को पूरी तरह से मॉडल करने की होगी। यह डोमेन एक्सेस राइट्स, ऑथराइजेशन आदि में रुचि रखता है। अकाउंटिंग सबडोमेन तब इस ऑथराइजेशन डोमेन को एक्सेस करने के लिए किसी सर्विस का इस्तेमाल करेगा AuthorizationService.isAuthorized(user, command)
।
class TAddTransactionCmdHandler(cmd) {
authService.isAuthorized(cmd)
.then(function(authorized){
if (!authorized) throw new Error('Not authorized');
return this.ledgerRepository.find(cmd.ledgerId)
})
.then(function(){
ledger.addTransaction(cmd);
})
}
किस निर्णय से सबसे अधिक "DDD / CQRS" होगा?