परिचय: TypeScript में कैशिंग की आवश्यकता क्यों?
\n\nआधुनिक वेब एप्लिकेशन को उच्च प्रतिक्रिया गति और डेटाबेस पर न्यूनतम लोड की आवश्यकता होती है। कैशिंग इसे प्राप्त करने के सबसे प्रभावी तरीकों में से एक है। TypeScript (और Node.js) इकोसिस्टम में, डेवलपर्स के पास तीन मुख्य दृष्टिकोण उपलब्ध हैं: वितरित सिस्टम (Redis, Memcached) और अंतर्निहित समाधान (in-memory cache)। इस लेख में, हम उनमें से प्रत्येक पर चर्चा करेंगे, TypeScript में व्यावहारिक उदाहरण प्रस्तुत करेंगे और आपके प्रोजेक्ट के लिए सर्वोत्तम विकल्प चुनने में मदद करेंगे।
\n\nकैशिंग आपको बार-बार अनुरोधित डेटा को तेज़ स्टोरेज में संग्रहीत करने की अनुमति देता है, जिससे महंगे संचालन (DB क्वेरी, गणना, बाहरी API कॉल) से बचा जा सकता है। एक सही कैशिंग रणनीति सर्वर प्रतिक्रिया समय को 10-100 गुना तक कम कर सकती है।
\n\n1. TypeScript में अंतर्निहित कैशिंग (In-Memory)
\n\nसबसे सरल तरीका है डेटा को सीधे Node.js प्रक्रिया की मेमोरी में संग्रहीत करना। इसके लिए किसी बाहरी सेवा की आवश्यकता नहीं है, जो छोटे एप्लिकेशन या प्रोटोटाइप के लिए आदर्श है।
\n\n1.1. Map और WeakMap का उपयोग
\n\nJavaScript के अंतर्निहित कलेक्शन एक सरल कैश के लिए एक उत्कृष्ट आधार हैं। TTL (Time To Live) के साथ कार्यान्वयन का उदाहरण:
\n\ntype CacheEntry<T> = {\n value: T;\n expiresAt: number;\n};\n\nclass SimpleCache<T> {\n private store = new Map<string, CacheEntry<T>>();\n\n set(key: string, value: T, ttlMs: number = 60000): void {\n this.store.set(key, {\n value,\n expiresAt: Date.now() + ttlMs,\n });\n }\n\n get(key: string): T | undefined {\n const entry = this.store.get(key);\n if (!entry) return undefined;\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n return entry.value;\n }\n\n delete(key: string): boolean {\n return this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n\n// उपयोग\nconst userCache = new SimpleCache<object>();\nuserCache.set('user:1', { name: 'अलेक्सेई' }, 30000); // TTL 30 सेकंड\nconsole.log(userCache.get('user:1'));\n\n1.2. node-cache लाइब्रेरी
\n\nप्रोडक्शन समाधानों के लिए, सिद्ध लाइब्रेरी node-cache का उपयोग करना बेहतर है। यह उन्नत सुविधाएँ प्रदान करती है: स्वचालित सफाई, सांख्यिकी और ईवेंट।
import NodeCache from 'node-cache';\n\nconst myCache = new NodeCache({ stdTTL: 100, checkperiod: 120 });\n\n// ऑब्जेक्ट सहेजें\nconst success = myCache.set('myKey', { data: 'value' });\nif (success) console.log('कैश सहेजा गया');\n\n// पढ़ें\nconst value = myCache.get('myKey');\nconsole.log(value); // { data: 'value' }\n\n// सांख्यिकी प्राप्त करें\nconst stats = myCache.getStats();\nconsole.log(`हिट्स: ${stats.hits}, मिसेज़: ${stats.misses}`);\n\nलाभ: सरलता, शून्य नेटवर्क विलंबता, सेवाओं की स्थापना की आवश्यकता नहीं।
\nनुकसान: एप्लिकेशन पुनरारंभ होने पर कैश खो जाता है, वितरित सिस्टम के लिए उपयुक्त नहीं है।
2. TypeScript में Redis के साथ कैशिंग
\n\nRedis प्रोडक्शन में कैशिंग के लिए सबसे लोकप्रिय समाधान है। यह एक अलग सर्वर के रूप में काम करता है, जटिल डेटा संरचनाओं का समर्थन करता है और एप्लिकेशन पुनरारंभ के लिए प्रतिरोधी है।
\n\n2.1. ioredis कनेक्ट करना
\n\nलाइब्रेरी ioredis TypeScript से Redis के साथ काम करने के लिए डी-फैक्टो मानक है। यह क्लस्टरिंग, Pub/Sub और Pipeline का समर्थन करती है।
import Redis from 'ioredis';\n\nconst redis = new Redis({\n host: 'localhost',\n port: 6379,\n retryStrategy: (times) => Math.min(times * 50, 2000),\n});\n\n// कनेक्शन जांच\nredis.on('connect', () => console.log('Redis से कनेक्टेड'));\nredis.on('error', (err) => console.error('Redis त्रुटि:', err));\n\n2.2. TTL के साथ कैशिंग का उदाहरण
\n\nasync function getCachedData(key: string): Promise<string | null> {\n const cached = await redis.get(key);\n if (cached) {\n console.log('डेटा कैश से');