عميل Redis لـ TypeScript: ioredis و redis (node-redis)
\n\nفي عالم تطبيقات الويب الحديثة والخدمات المصغرة، يُعتبر Redis أحد أشهر مخازن البيانات في الذاكرة العاملة. يُستخدم للتخزين المؤقت، إدارة الجلسات، قوائم المهام، Pub/Sub، والعديد من الاستخدامات الأخرى. إذا كنت تطور باستخدام TypeScript، فستحتاج إلى عميل موثوق للتفاعل مع Redis. في هذه المقالة، سنستعرض خيارين رئيسيين: ioredis و redis (المعروف أيضًا باسم node-redis). كلا المكتبتين تتمتعان بدعم ممتاز لـ TypeScript، ويتم صيانتهما بنشاط، وتوفران مجموعة واسعة من الإمكانيات.
\n\nلماذا تحتاج إلى عميل Redis لـ TypeScript؟
\nيضيف TypeScript كتابة ثابتة (static typing) إلى JavaScript، مما يجعل الكود أكثر قابلية للتنبؤ ويقلل من عدد الأخطاء في مرحلة التطوير. يتيح لك عميل Redis لـ TypeScript ما يلي:
\n- \n
- العمل مع أوامر Redis بدعم كامل للأنواع. \n
- استخدام الإكمال التلقائي في بيئة التطوير المتكاملة (IntelliSense).
- التكامل بسهولة مع الأطر الحديثة (NestJS، Express، Koa).
- تبسيط معالجة الأخطاء وإعادة الاتصال.
مكتبة ioredis
\nioredis هو عميل Redis كامل الوظائف، وكان لوقت طويل المعيار الفعلي في نظام Node.js البيئي. يدعم التجميع (clustering)، Pub/Sub، خطوط الأنابيب (pipelining)، المعاملات (MULTI/EXEC)، إعادة الاتصال التلقائي، وغيرها الكثير. ioredis مكتوب بـ TypeScript ويوفر الأنواع (types) مباشرة.
\n\nالتثبيت
\nnpm install ioredis\nnpm install @types/ioredis # إذا كنت تستخدم TypeScript < 4.0\n\nمثال على الاتصال والعمليات الأساسية
\nimport Redis from 'ioredis';\n\n// إنشاء اتصال بـ Redis (افتراضيًا localhost:6379)\nconst redis = new Redis();\n\n// دالة غير متزامنة للتوضيح\nasync function demo() {\n try {\n // تعيين قيمة\n await redis.set('user:1:name', 'آنا');\n await redis.set('user:1:age', 30);\n\n // الحصول على قيمة\n const name = await redis.get('user:1:name');\n console.log('اسم المستخدم:', name);\n\n // العمل مع التجزئات (hashes)\n await redis.hset('user:2', 'name', 'إيفان', 'age', 25);\n const user2 = await redis.hgetall('user:2');\n console.log('المستخدم 2:', user2);\n\n // الزيادة (increment)\n const views = await redis.incr('page:home:views');\n console.log('مشاهدات الصفحة:', views);\n\n // تعيين مع انتهاء الصلاحية (TTL)\n await redis.setex('temp:code', 60, '123456');\n const ttl = await redis.ttl('temp:code');\n console.log('الوقت المتبقي لعمر المفتاح:', ttl, 'ثانية');\n\n } catch (error) {\n console.error('خطأ Redis:', error);\n } finally {\n // إغلاق الاتصال\n redis.disconnect();\n }\n}\n\ndemo();\n\nدعم المجموعات (Clusters) و Pub/Sub
\nيعمل ioredis بشكل ممتاز مع مجموعات Redis. لهذا الغرض، يُستخدم الصنف الخاص Cluster:
import Redis from 'ioredis';\n\nconst cluster = new Redis.Cluster([\n { host: '127.0.0.1', port: 7000 },\n { host: '127.0.0.1', port: 7001 },\n { host: '127.0.0.1', port: 7002 }\n]);\n\nawait cluster.set('foo', 'bar');\nconst value = await cluster.get('foo');\nconsole.log(value); // 'bar'\n\nبالنسبة لـ Pub/Sub، يُستخدم اتصال منفصل، لأن المشترك لا يمكنه تنفيذ الأوامر العادية:
\nimport Redis from 'ioredis';\n\nconst subscriber = new Redis();\nconst publisher = new Redis();\n\nsubscriber.subscribe('news', (err, count) => {\n console.log(`مشترك في ${count} قناة(قنوات)`);\n});\n\nsubscriber.on('message', (channel, message) => {\n console.log(`تم استلام رسالة من القناة ${channel}: ${message}`);\n});\n\n// نشر رسالة\npublisher.publish('news', 'مرحبًا من TypeScript!');\n\nمكتبة redis (node-redis)
\nredis (الحزمة redis على n