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

الوسيطات (Middleware)

15 دقيقة الدرس 12 من 30

الوسيطات (Middleware)

الوسيط (Middleware) دالّة تعمل قبل معالج المسار، ولديها وصول إلى كائني الطلب والاستجابة. إن عرفت وسيطات Express فهذا المفهوم نفسه — يمنحه NestJS بنية فقط ويربطه بنظام الوحدات. وهو أوّل ما يعمل في دورة حياة الطلب.

فيمَ تُستخدَم الوسيطات

تعالج الوسيطات الاهتمامات العابرة التي تحدث قبل منطق التوجيه: تسجيل الطلبات، وإرفاق خصائص بالطلب، وتحليل الجسم الخام، وCORS، ومهام منخفضة المستوى مشابهة. يمكنها تشغيل كود، أو تعديل req/res، أو إنهاء الطلب، أو استدعاء next() للمتابعة.

الوسيط الدالّي

أبسط صورة دالّة عاديّة:

import { Request, Response, NextFunction } from 'express'; export function logger(req: Request, res: Response, next: NextFunction) { console.log(`${req.method} ${req.originalUrl}`); next(); // تمرير التحكّم إلى المعالج التالي }
استدعِ next() دائمًا (أو أنهِ الاستجابة). إن لم يستدعِ الوسيط next() ولم يُرسل استجابة، يتعلّق الطلب إلى الأبد. وهذا أشيع أخطاء الوسيطات.

وسيط الصنف

للوسيط الذي يحتاج حقن تبعيات، نفّذ واجهة NestMiddleware:

import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; @Injectable() export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { console.log(`Request to ${req.path}`); next(); } }

تطبيق الوسيط

لا يُعلَن الوسيط في بيانات @Module(). بل تُنفّذ الوحدة واجهة NestModule وتضبطه في دالّة configure():

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; @Module({ controllers: [UsersController] }) export class UsersModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LoggerMiddleware) .forRoutes('users'); // أو متحكّم، أو { path, method } } }

تستطيع استهداف مسارات أو طرق أو متحكّمات محدّدة، واستخدام .exclude() لتخطّي بعض المسارات.

الوسيط مقابل الحارس مقابل المعترِض

يعمل الوسيط أوّلًا، قبل أن يعرف NestJS أي مسار أو معالج سيعمل. وهذا يجعله مثاليًا للعمل العام غير المرتبط بمسار — لكنه أداة خاطئة للتفويض أو تشكيل الاستجابة:

  • الوسيط — معالجة أوّلية عامة (تسجيل، ترويسات، جسم خام). بلا وصول إلى المعالج الذي سيعمل.
  • الحُرّاس — قرارات تفويض، بسياق تنفيذ كامل.
  • المعترِضات — تغليف المعالج لتحويل الطلب/الاستجابة.
الجأ للوسيط فقط حين تحتاجه أن يعمل قبل كل شيء آخر ولا تحتاج سياقًا خاصًّا بـ NestJS (كالمعالج الهدف أو بياناته الوصفية). للتفويض استخدم حارسًا؛ ولتحويل الاستجابة استخدم معترِضًا.

الخلاصة

يعمل الوسيط أوّلًا في دورة حياة الطلب، قبل الحُرّاس والأنابيب والمعالج. اكتبه كدالّة أو صنف NestMiddleware، وطبّقه عبر دالّة configure(consumer) في الوحدة مستهدفًا مسارات محدّدة. استخدمه للمعالجة الأوّلية العامة — والجأ للحُرّاس أو المعترِضات حين تحتاج سياق NestJS. تاليًا: الحُرّاس، الذين يقرّرون هل يُسمح للطلب بالمتابعة.