تحديد معدل الطلبات في TypeScript: دليل كامل للمكتبات والتنفيذ
\n\nتحديد معدل الطلبات (Rate Limiting) هو آلية للتحكم في حركة المرور تمنع تحميل الخادم الزائد، وتحمي من هجمات DDoS، وتضمن توزيعًا عادلًا للموارد. في TypeScript، بفضل الكتابة الصارمة ودعم العمليات غير المتزامنة، يصبح تنفيذ تحديد معدل الطلبات مريحًا بشكل خاص. في هذه المقالة، سنستعرض المكتبات الشائعة والاستراتيجيات وأمثلة الكود لـ TypeScript.
\n\nلماذا نحتاج إلى تحديد معدل الطلبات؟
\n- \n
- حماية API — تحديد عدد الطلبات من عميل واحد (عن طريق IP، رمز مميز أو ID). \n
- منع إساءة الاستخدام — حظر الروبوتات أو البرامج النصية التي تولد حمولة زائدة. \n
- توزيع الموارد — الاستخدام العادل للخادم الخلفي بين المستخدمين. \n
- الامتثال لحدود الخدمات الخارجية — التحكم في الطلبات إلى واجهات API الخارجية (مثل OpenAI أو GitHub). \n
المكتبات الشائعة لتحديد معدل الطلبات في TypeScript
\n\n1. express-rate-limit
\nالمكتبة الأكثر شيوعًا لـ Express.js. تعمل كـ middleware، وتدعم TypeScript بشكل افتراضي. تسمح بتعيين حد زمني ومعالجات مخصصة للتجاوز.
\nالتثبيت:
\nnpm install express-rate-limit\nnpm install -D @types/express-rate-limit\nمثال على الاستخدام:
\nimport express from 'express';\nimport rateLimit from 'express-rate-limit';\n\nconst app = express();\n\nconst limiter = rateLimit({\n windowMs: 15 * 60 * 1000, // 15 دقيقة\n max: 100, // الحد الأقصى 100 طلب لكل نافذة\n message: 'عدد كبير جدًا من الطلبات، حاول مرة أخرى لاحقًا.',\n standardHeaders: true,\n legacyHeaders: false,\n});\n\napp.use('/api', limiter); // تطبيق على /api/*\n\napp.get('/api/data', (req, res) => {\n res.json({ message: 'استجابة ناجحة' });\n});\n\napp.listen(3000);\nالميزات:
\n- \n
- دعم مدمج لـ TypeScript (أنواع لـ
RequestوResponse). \n - إعدادات مرنة: يمكن تعيين المفتاح (عن طريق IP، userId، رمز مميز). \n
- تخزين الحالة في الذاكرة (افتراضيًا) أو عبر Redis. \n
2. bottleneck
\nمكتبة لتحديد معدل الطلبات من جانب العميل — مثالية عندما تحتاج إلى التحكم في الطلبات الصادرة (مثلًا إلى API خارجي). تعمل بناءً على قوائم الانتظار والتأخيرات.
\nالتثبيت:
\nnpm install bottleneck\nمثال مع TypeScript:
\nimport Bottleneck from 'bottleneck';\n\nconst limiter = new Bottleneck({\n minTime: 200, // 200 مللي ثانية على الأقل بين الطلبات\n maxConcurrent: 5, // 5 طلبات متزامنة كحد أقصى\n reservoir: 100, // الحد الإجمالي للفترة\n reservoirRefreshAmount: 100,\n reservoirRefreshInterval: 60 * 1000, // كل 60 ثانية\n});\n\nasync function fetchData(id: number): Promise<string> {\n const response = await fetch(`https://api.example.com/data/${id}`);\n return response.text();\n}\n\n// تغليف الدالة مع تحديد المعدل\nconst limitedFetch = limiter.wrap(fetchData);\n\n// الاستخدام\nasync function main() {\n const results = await Promise.all([\n limitedFetch(1),\n limitedFetch(2),\n limitedFetch(3),\n ]);\n console.log(results);\n}\nالمزايا:
\n- \n
- يدعم الأنواع للدالة المغلفة. \n
- استراتيجيات مرنة:
minTime،maxConcurrent،reservoir. \n - يعمل في كل من Node.js والمتصفح. \n
3. p-limit
\nمكتبة خفيفة الوزن لتحديد العمليات غير المتزامنة المتوازية. مفيدة عندما تحتاج إلى التحكم في عدد الوعود (Promises) المنفذة في وقت واحد.
\nالتثبيت:
\nnpm install p-