NestJS — Node.js للمؤسسات

سياق التنفيذ و ArgumentsHost

18 دقيقة الدرس 49 من 80

سياق التنفيذ و ArgumentsHost

تعمل تطبيقات NestJS غالباً عبر أكثر من وسيلة نقل: متحكمات HTTP، ومحللات GraphQL، وبوابات WebSocket، ومعالجات الخدمات المصغرة. تساعد أدوات سياق التنفيذ على كتابة حراس ومرشحات ومعترضات ومزخرفات تعرف أين تعمل بدلاً من ربط الكود دائماً بكائن طلب Express.

الفكرة الأساسية

تدور هذه الميزة حول التحكم في كيفية تنظيم التطبيق وسلوكه وقت التشغيل. النقاط التالية هي ما يجب أن يعرفه المطور قبل استخدامها في مشروع حقيقي:

  • يغلف ArgumentsHost الوسائط الخام للمعالج ويمكنه التحول إلى عرض HTTP أو RPC أو WebSocket.
  • يوسع ExecutionContext الفئة ArgumentsHost بدوال getClass() و getHandler() لمعرفة صنف المتحكم ودالة المسار الجاري تنفيذها.
  • ينبغي للمكونات العامة استدعاء getType() قبل قراءة بيانات الطلب حتى لا تنكسر في GraphQL أو الخدمات المصغرة.
  • تُقرأ بيانات Reflector عادة من context.getHandler() و context.getClass() حتى تستطيع قواعد الدالة تجاوز قواعد الصنف.
  • استخدم switchToHttp() و switchToRpc() و switchToWs() بدلاً من getArgByIndex() إلا عند بناء محول منخفض المستوى جداً.

مثال عملي

يوضح المثال التالي الشكل العملي للفكرة داخل مشروع NestJS. ليست الغاية حفظ الكود، بل فهم مكانه في المعمارية:

@Injectable() export class TransportAwareGuard implements CanActivate { constructor(private readonly reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const roles = this.reflector.getAllAndOverride<string[]>('roles', [ context.getHandler(), context.getClass(), ]); if (context.getType() === 'http') { const request = context.switchToHttp().getRequest(); return this.userHasRole(request.user, roles); } if (context.getType() === 'rpc') { const data = context.switchToRpc().getData(); return this.tokenHasRole(data.authToken, roles); } return true; } }
ملاحظة تصميمية: يمثل ExecutionContext الجسر بين تجريدات NestJS ووسيلة النقل الفعلية. اجعل المنطق القابل لإعادة الاستخدام واعياً بوسيلة النقل ليخدم REST اليوم وGraphQL أو الخدمات المصغرة لاحقاً.

قائمة تطبيق إنتاجية

  • فضّل switchToHttp()/switchToRpc()/switchToWs() على فهارس المصفوفة المباشرة.
  • ادمج بيانات الدالة والصنف عند بناء الحراس أو المعترضات.
  • اجعل الوصول الخاص بـ GraphQL خلف GqlExecutionContext.create(context).
  • اختبر الحراس المشتركة على مسار HTTP وسياق غير HTTP قبل تعميمها.
قاعدة عملية: إذا جعلت الميزة الحدود أوضح والاختبارات أسهل فهي اختيار جيد. إذا أخفت التبعيات أو صعّبت التتبع، فأعد التصميم.

الخلاصة

يغطي هذا الدرس جزءاً متقدماً من NestJS يجب فهمه عند بناء تطبيقات مؤسسية. ركّز على الحدود الواضحة، والسلوك القابل للاختبار، واختيار الأداة المناسبة للسياق بدلاً من استخدام كل ميزة في كل مكان.