أنماط الرسائل والأحداث
أنماط الرسائل والأحداث
تتواصل الخدمات المصغّرة في NestJS عبر نمطين أساسيين: الطلب-الاستجابة (الرسائل) والإطلاق والنسيان (الأحداث). يُحدّد الاختيار بينهما طريقة عزل الخدمات، وكيفية انتشار الأخطاء، وما إذا كان المستدعي يتوقّف منتظرًا ردًّا. إتقان كلا النمطين — والمزخرفات وأساليب الـ proxy التي تُطبّقهما — هو العمود الفقري لأي بنية خدمات مصغّرة في NestJS.
@MessagePattern — الطلب-الاستجابة
يُشارك معالج مُزخرف بـ @MessagePattern في تبادل طلب-استجابة. يُرسل المستدعي رسالة وينتظر الرد. يُشبه هذا استدعاء HTTP التقليدي: يتوقّف العميل (أو يُكمل await على Promise) حتى يُعيد المعالج البعيد قيمة أو يرمي خطأً.
كائن النمط ({ cmd: 'get_order' }) هو مفتاح التوجيه. يمكن أن يكون نصًّا حرفيًّا أو أي كائن قابل للتسلسل، بشرط اتّفاق الطرفين على نفس القيمة.
@EventPattern — الإطلاق والنسيان
يستقبل معالج مُزخرف بـ @EventPattern الأحداث. لا ينتظر الناشر ردًّا — يُطلق الحدث ويمضي فورًا. هذا مثالي للآثار الجانبية كإرسال رسائل بريد إلكتروني، أو تحديث نماذج القراءة، أو كتابة سجلات التدقيق، حيث لا يهتم الناشر بالنتيجة.
@MessagePattern فقط حين يحتاج المستدعي إلى نتيجة.
ClientProxy — الإرسال من المستدعي
على جانب المستدعي، أدخِل ClientProxy (المُنتَج بواسطة ClientsModule.register) واختر الأسلوب المناسب:
client.send(pattern, payload)— لـ@MessagePattern؛ يُعيد Observable يحلّ بالرد.client.emit(pattern, payload)— لـ@EventPattern؛ يُعيد Observable يكتمل عند إرسال الرسالة (وليس عند معالجتها).
ClientProxy.send() Observable من RxJS لا Promise. لُفّها بـ firstValueFrom() (من rxjs) لاستخدامها بسهولة ضمن كود async/await. لا تُهمل الاشتراك — Observable غير مُشترك فيه لا ينفّذ أبدًا.
معالجة الحمولة والسياق
استخدم @Payload() لاستخراج بيانات الرسالة و@Ctx() للوصول إلى السياق الخاص بطبقة النقل (الترويسات، دوال الإقرار، معلومات التقسيم، وغيرها):
client.send() مقابل معالج مُسجَّل بـ @EventPattern سيتعلّق إلى الأبد منتظرًا ردًّا لن يأتي. واستدعاء client.emit() مقابل معالج @MessagePattern يعني إهمال ردّك — لا يحصل المستدعي على شيء. اجعل الزوج متّسقًا دائمًا.
الخلاصة
تُقدّم خدمات NestJS المصغّرة بدائل تواصل أساسية: @MessagePattern + ClientProxy.send() للطلب-الاستجابة (يُكمل المستدعي await ردًّا)، و@EventPattern + ClientProxy.emit() للإطلاق والنسيان (لا يُتوقَّع رد). استخدم @Payload() للوصول إلى بيانات الرسالة و@Ctx() لسياق النقل. طابق دائمًا المُزخرف على المعالج مع أسلوب الـ proxy الصحيح على المستدعي — فالأخطاء هنا تؤدّي إلى فشل صامت.