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

خطّافات دورة الحياة وسياق التطبيق

16 دقيقة الدرس 18 من 48

خطّافات دورة الحياة وسياق التطبيق

لتطبيق NestJS حياة: يُقلع، ويعمل، ويُغلَق. تتيح خطّافات دورة الحياة لمزوّداتك تشغيل كود في لحظات دقيقة — فتح اتصال قاعدة بيانات بعد التهيئة، أو إغلاقه بنظافة عند الإغلاق. وحُسن استخدامها يجعل تطبيقك موثوقًا وآمنًا للموارد.

تسلسل دورة الحياة

يستدعي NestJS دوال الخطّافات بترتيب محدّد أثناء الإقلاع والإنهاء. وأفيدها:

  • onModuleInit() — يعمل بمجرّد حلّ تبعيات الوحدة المضيفة.
  • onApplicationBootstrap() — يعمل بعد تهيئة كل الوحدات.
  • onModuleDestroy() — يعمل حين يبدأ التطبيق بالإغلاق.
  • onApplicationShutdown(signal) — يعمل أخيرًا، مع إشارة الإنهاء.

تنفيذ خطّاف

نفّذ الواجهة المطابقة والدالّة على مزوّد:

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; @Injectable() export class DatabaseService implements OnModuleInit, OnModuleDestroy { async onModuleInit() { await this.connect(); // افتح الاتصال عند الإقلاع console.log('DB connected'); } async onModuleDestroy() { await this.disconnect(); // أغلقه بنظافة عند الإغلاق console.log('DB disconnected'); } }
الخطّافات يمكن أن تكون async. ينتظر NestJS دالّة onModuleInit() غير المتزامنة قبل اعتبار الوحدة جاهزة، فلن يبدأ التطبيق بخدمة الطلبات حتى تنتهي تهيئتك.

الإغلاق الرشيق

تعمل خطّافات الإغلاق فقط إن فعّلت مستمعي الإغلاق صراحةً — وهذا ما يتيح للحاوية تصريف الطلبات الجارية وتحرير الموارد قبل خروج العملية:

// main.ts const app = await NestFactory.create(AppModule); app.enableShutdownHooks(); // مطلوب لـ onModuleDestroy / onApplicationShutdown await app.listen(3000);
onApplicationShutdown لن يعمل افتراضيًا. دون app.enableShutdownHooks()، تتجاوز إشارات الإنهاء (SIGTERM/SIGINT) تنظيفك. في النشر الحاوي، نسيان هذا يُسرّب الاتصالات ويُسقِط العمل الجاري.

سياق التطبيق المستقلّ

أحيانًا تريد حقن تبعيات NestJS ومزوّداته دون خادم HTTP — لأمر CLI، أو سكربت مجدوَل، أو مهمّة لمرّة واحدة. تبني createApplicationContext() ذلك بالضبط:

import { NestFactory } from '@nestjs/core'; async function runTask() { const app = await NestFactory.createApplicationContext(AppModule); const reportService = app.get(ReportService); // احصل على أي مزوّد await reportService.generateDaily(); await app.close(); // يُطلِق خطّافات الإغلاق }
تتجاوز app.get() المتحكّم. يتيح لك سياق التطبيق سحب أي مزوّد من الحاوي واستدعاءه مباشرة — مثالي للبذور والترحيلات والمهام المجدوَلة التي تعيد استخدام خدماتك دون طبقة HTTP.

الخلاصة

تتيح خطّافات دورة الحياة (onModuleInit وonApplicationBootstrap وonModuleDestroy وonApplicationShutdown) للمزوّدات تشغيل الإعداد والتفكيك في اللحظات الصحيحة؛ وتذكّر app.enableShutdownHooks() للإغلاق الرشيق. ويعيد سياق التطبيق المستقلّ (createApplicationContext + app.get()) استخدام حقن تبعياتك وخدماتك دون خادم HTTP. تاليًا: أنماط المعماريّة التي تربط هذا كلّه.