ठीक है, जबकि मैं अपने से बेहतर उत्तर की प्रतीक्षा कर रहा हूं, मैं अब तक जो कर रहा हूं उसे पोस्ट करने का प्रयास करूंगा।
मिडलवेयर से पहले/पोस्ट करें
पहली चीज़ जो मैंने कोशिश की वह थी पूर्व/पोस्ट मिडलवेयर
का उपयोग करना। एक दूसरे को संदर्भित करने वाले दस्तावेज़ों को सिंक्रनाइज़ करने के लिए। (उदाहरण के लिए, यदि आपके पास Author
. है और Quote
, और एक लेखक के पास इस प्रकार की एक सरणी होती है:quotes: [{type: Schema.Types.ObjectId, ref:'Quotes'}]
, फिर जब भी कोई कोट हटा दिया जाता है, तो आपको उसका _id
हटाना होगा सरणी से। या यदि लेखक को हटा दिया जाता है, तो हो सकता है कि आप उसके सभी उद्धरण हटा देना चाहें)।
इस दृष्टिकोण का एक महत्वपूर्ण लाभ है :यदि आप प्रत्येक स्कीमा को उसकी अपनी फ़ाइल में परिभाषित करते हैं, तो आप वहां मिडलवेयर को परिभाषित कर सकते हैं और यह सब सुव्यवस्थित कर सकते हैं . जब भी आप स्कीमा को देखते हैं, तो ठीक नीचे आप देख सकते हैं कि यह क्या करता है, इसके परिवर्तन अन्य संस्थाओं को कैसे प्रभावित करते हैं, आदि:
var Quote = new Schema({
//fields in schema
})
//its quite clear what happens when you remove an entity
Quote.pre('remove', function(next) {
Author.update(
//remove quote from Author quotes array.
)
})
मुख्य नुकसान हालांकि यह है कि जब आप अद्यतन या किसी मॉडल स्थिर अद्यतन/निकालने के कार्यों को कॉल करते हैं तो ये हुक निष्पादित नहीं होते हैं
. इसके बजाय आपको दस्तावेज़ को पुनः प्राप्त करने की आवश्यकता है और फिर save()
. पर कॉल करें या remove()
उन पर।
एक और छोटा नुकसान यह है कि Quote को अब किसी ऐसे व्यक्ति के बारे में पता होना चाहिए जो इसका संदर्भ देता है, ताकि जब भी कोई Quote अपडेट या हटाया जाए तो वह उन्हें अपडेट कर सके। तो मान लें कि एक Period
उद्धरणों की एक सूची है, और Author
उद्धरणों की एक सूची भी है, उद्धरण को अद्यतन करने के लिए इन दोनों के बारे में जानना होगा।
इसका कारण यह है कि ये फ़ंक्शन सीधे डेटाबेस में परमाणु प्रश्न भेजते हैं। हालांकि यह अच्छा है, मुझे save()
. का उपयोग करने के बीच असंगतता से नफरत है और Model.Update(...)
. हो सकता है कि कोई और या आप भविष्य में गलती से स्टैटिक अपडेट फ़ंक्शंस का उपयोग कर लें और आपका मिडलवेयर ट्रिगर न हो, जिससे आपको सिरदर्द हो जिससे आप छुटकारा पाने के लिए संघर्ष करते हैं।
NodeJS इवेंट मैकेनिज्म
मैं वर्तमान में जो कर रहा हूं वह वास्तव में इष्टतम नहीं है, लेकिन यह मुझे वास्तव में विपक्ष को पछाड़ने के लिए पर्याप्त लाभ प्रदान करता है (या तो मुझे विश्वास है, अगर कोई मुझे कुछ प्रतिक्रिया देने की परवाह करता है तो यह बहुत अच्छा होगा)। मैंने एक ऐसी सेवा बनाई है जो एक मॉडल के इर्द-गिर्द घूमती है, जैसे AuthorService
जो events.EventEmitter
. का विस्तार करता है और एक कंस्ट्रक्टर फ़ंक्शन है जो मोटे तौर पर इस तरह दिखेगा:
function AuthorService() {
var self = this
this.create = function() {...}
this.update = function() {
...
self.emit('AuthorUpdated, before, after)
...
}
}
util.inherits(AuthorService, events.EventEmitter)
module.exports = new AuthorService()
फायदे:
- कोई भी इच्छुक समारोह Serviceevents में पंजीकृत हो सकता है और अधिसूचित किया जा सकता है। इस तरह, उदाहरण के लिए, जब कोई
Quote
अद्यतन किया गया है, AuthorService इसे सुन सकता है औरAuthors
को अपडेट कर सकता है इसलिए। (नोट 1) - उद्धरण को उन सभी दस्तावेजों से अवगत होने की आवश्यकता नहीं है जो इसका संदर्भ देते हैं, सेवा केवल
QuoteUpdated
को ट्रिगर करती है घटना और सभी दस्तावेज़ जिन्हें ऐसा होने पर संचालन करने की आवश्यकता होती है, ऐसा करेंगे।
नोट 1:जब तक इस सेवा का उपयोग तब तक किया जाता है जब भी किसी को नेवले के साथ बातचीत करने की आवश्यकता होती है।
नुकसान:
- नेवले के बजाय सीधे सेवा का उपयोग करके बॉयलरप्लेट कोड जोड़ा गया।
- अब यह बिल्कुल स्पष्ट नहीं है कि जब आप ईवेंट को ट्रिगर करते हैं तो कौन से फ़ंक्शन कॉल किए जाते हैं।
- आप निर्माता और उपभोक्ता को सुगमता की कीमत पर अलग करते हैं (चूंकि आप केवल
emit('EventName', args)
, यह तुरंत स्पष्ट नहीं है कि कौन सी सेवाएं इस घटना को सुन रही हैं)
एक और नुकसान यह है कि कोई व्यक्ति सेवा से एक मॉडल प्राप्त कर सकता है और save()
. पर कॉल कर सकता है , जिसमें ईवेंट ट्रिगर नहीं होंगे हालांकि मुझे यकीन है कि इन दो समाधानों के बीच किसी प्रकार के संकर के साथ इसे संबोधित किया जा सकता है।
मैं इस क्षेत्र में सुझावों के लिए बहुत खुला हूं (इसीलिए मैंने इस प्रश्न को सबसे पहले पोस्ट किया है)।