CQRS और Event Sourcing Kotlin में: बेहतरीन कोड के लिए आर्किटेक्चर

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

CQRS और Event Sourcing सिर्फ ट्रेंडिंग शब्द क्यों नहीं हैं

\n\n

कल्पना करें कि आपका कोड एक विशाल संग्रहालय है। आमतौर पर हम केवल आखिरी वर्जन ही स्टोर करते हैं: "अब ऑर्डर ऐसा दिखता है"। लेकिन क्या होगा अगर हम जानना चाहें कि कैसे ऑर्डर इस स्थिति में पहुंचा? "भेजें" बटन किसने दबाया? स्टेटस कब बदला? यहीं पर CQRS (Command Query Responsibility Segregation) और Event Sourcing Kotlin में काम आते हैं।

\n\n

इस गाइड में हम सिर्फ Wikipedia से थ्योरी कॉपी नहीं करेंगे। हम असली उदाहरणों को समझेंगे, कोड लिखेंगे और जानेंगे कि कैसे ये पैटर्न CRUD ऑपरेशंस की अव्यवस्था को एक सुव्यवस्थित आर्किटेक्चर में बदल देते हैं। अगर आप "स्पेगेटी कोड" से थक गए हैं और ऐसे सिस्टम बनाना चाहते हैं जिन्हें आसानी से स्केल और डीबग किया जा सके, तो आप सही जगह पर हैं।

\n\n

सरल शब्दों में CQRS क्या है

\n\n

स्टैंडर्ड आर्किटेक्चर में हम डेटा पढ़ने और लिखने के लिए एक ही मॉडल का उपयोग करते हैं। यह ऐसा है जैसे आप सूप खा रहे हों और उसी चम्मच से उसे हिला रहे हों। CQRS जिम्मेदारी को अलग करने का सुझाव देता है:

\n\n
    \n
  • Command (कमांड) — स्थिति बदलता है। राइट रिक्वेस्ट (Create, Update, Delete)।
  • \n
  • Query (क्वेरी) — स्थिति पढ़ता है। केवल SELECT ऑपरेशंस।
  • \n
\n\n

इसकी आवश्यकता क्यों है? एक ऑनलाइन स्टोर की कल्पना करें। जब उपयोगकर्ता ऑर्डर देता है, तो हमें इन्वेंट्री चेक करनी होती है, प्रोडक्ट डिडक्ट करना होता है, DB में एंट्री बनानी होती है, ईमेल भेजना होता है। यह एक जटिल कमांड है। जबकि ग्राहक सिर्फ अपने ऑर्डर की लिस्ट देखता है — यह एक सरल क्वेरी है। इन्हें एक ही मेथड में मिलाना बग्स का सीधा रास्ता है।

\n\n

Kotlin में CQRS के लाभ

\n
    \n
  • परफॉरमेंस: रीड और राइट को अलग-अलग ऑप्टिमाइज़ किया जा सकता है (अलग DB, कैश, इंडेक्स)।
  • \n
  • सुरक्षा: एक्सेस राइट्स को अलग करना (एडमिन लिखता है, उपयोगकर्ता पढ़ता है)।
  • \n
  • स्केलिंग: कमांड और क्वेरी को अलग-अलग सर्वर पर रखा जा सकता है।
  • \n
\n\n

Event Sourcing: तथ्यों के बजाय इतिहास सहेजना

\n\n

अगर CQRS ऑपरेशंस को अलग करता है, तो Event Sourcing डेटा स्टोर करने का तरीका बदलता है। वर्तमान स्थिति (जैसे, "बैलेंस: 1000 रुपये") स्टोर करने के बजाय, हम घटनाओं का एक क्रम स्टोर करते हैं: "500 का जमा", "200 की खरीदारी", "50 कमीशन कटौती"।

\n\n

वर्तमान स्थिति सिर्फ सभी घटनाओं को क्रम से लागू करने का परिणाम है। यह एक सुपरपावर देता है: हम समय को पीछे "रिवाइंड" कर सकते हैं, किसी भी तारीख पर स्थिति को पुनर्स्थापित कर सकते हैं, या उपयोगकर्ता के व्यवहार का विश्लेषण कर सकते हैं।

\n\n

जीवन से उदाहरण: बैंक खाता

\n
// इवेंट\ndata class MoneyDeposited(val amount: BigDecimal, val timestamp: Instant)\ndata class MoneyWithdrawn(val amount: BigDecimal, val timestamp: Instant)\n\n// एग्रीगेट (एंटिटी)\nclass BankAccount {\n    private var balance: BigDecimal = BigDecimal.ZERO\n    private val events = mutableListOf<Any>()\n\n    fun deposit(amount: BigDecimal) {\n        if (amount <= BigDecimal.ZERO) throw IllegalArgumentException("राशि सकारात्मक होनी चाहिए")\n        val event = MoneyDeposited(amount, Instant.now())\n        apply(event)\n        events.add(event)\n    }\n\n    fun withdraw(amount: BigDecimal) {\n        if (amount > balance) throw IllegalStateException("अपर्याप्त धनराशि")\n        val event = MoneyWithdrawn(amount, Instant.now())\n        apply(event)\n        events.add(event)\n    }\n\n    private fun apply(event: Any) {\n        when (event) {\n            is MoneyDeposited -> balance += event.amount\n            is MoneyWithdrawn -> balance -= event.amount\n        }\n    }\n\n    fun getBalance(): BigDecimal = balance\n    fun getUncommittedEvents(): List<Any> = events.toList()\n}
\n\n

CQRS और Event Sourcing एक साथ कैसे काम करते हैं

\n\n

यह एक क्लासिक जोड़ी है। CQRS चैनलों को अलग करने के लिए जिम्मेदार है, और Event Sourcing स्टोर करने के लिए जिम्मेदार है

ब्लॉग

पुस्तक अनुशंसाएँ