مقدمة: لماذا TypeScript هو الخيار الأمثل للميكروسيرفيسات
التطوير الحديث لأنظمة الواجهة الخلفية يبتعد بشكل متزايد عن الأنظمة المتجانسة لصالح بنية الميكروسيرفيسات. TypeScript، كونه طبقة علوية ذات كتابة صارمة فوق JavaScript، يقدم مزيجاً فريداً من المرونة والموثوقية. تتيح الكتابة الثابتة في مرحلة التجميع اكتشاف أخطاء التكامل بين الخدمات قبل وصولها إلى بيئة الإنتاج، بينما يوفر النظام البيئي الغني (NestJS، Express، Fastify) أدوات جاهزة لبناء الأنظمة الموزعة.
في هذه المقالة، سنستعرض الدورة الكاملة: من تصميم الهندسة إلى نشر الميكروسيرفيسات باستخدام TypeScript. ستتعلم كيفية تنظيم التفاعل بين الخدمات، وإعداد وسطاء الرسائل، وضمان تحمل الأخطاء.
1. هندسة الميكروسيرفيسات باستخدام TypeScript: المبادئ الأساسية
1.1 تحليل مجال العمل
الخطوة الأولى هي تقسيم منطق الأعمال إلى خدمات مستقلة. كل ميكروسيرفيس مسؤول عن مجاله المحدود (Bounded Context). في TypeScript، يتم التعبير عن ذلك بشكل طبيعي من خلال الوحدات والحزم.
مثال على التحليل لمتجر إلكتروني:
- Auth Service — المصادقة ورموز JWT
- Product Service — كتالوج المنتجات والأسعار
- Order Service — إنشاء الطلبات وسجلها
- Payment Service — معالجة المدفوعات
كل خدمة هي تطبيق مستقل باستخدام TypeScript مع ملف package.json خاص بها، وإعدادات، ونقطة دخول (main.ts).
1.2 اختيار مجموعة التقنيات
لبداية سريعة، يُوصى باستخدام NestJS — وهو إطار عمل يدعم أنماط الميكروسيرفيسات بشكل افتراضي. يوفر محولات نقل لـ TCP و Redis و RabbitMQ و Kafka و gRPC.
المجموعة الأساسية:
- اللغة: TypeScript (الوضع الصارم، strict: true)
- إطار العمل: NestJS
- وسيط الرسائل: RabbitMQ (عبر @nestjs/microservices)
- قاعدة البيانات: PostgreSQL (كل خدمة لها قاعدة بياناتها الخاصة)
- الحاويات: Docker + Docker Compose
1.3 أنماط التفاعل
هناك نهجان رئيسيان: متزامن (HTTP/gRPC) وغير متزامن (قوائم الانتظار). للعمليات الحساسة للوقت، استخدم الطلبات المتزامنة، وللمهام الخلفية استخدم قوائم الانتظار.
مثال على إعداد خدمة هجينة في NestJS:
// main.ts — نقطة دخول الميكروسيرفيسimport { NestFactory } from '@nestjs/core';import { MicroserviceOptions, Transport } from '@nestjs/microservices';import { AppModule } from './app.module';
async function bootstrap() { // خادم HTTP لواجهة REST API const app = await NestFactory.create(AppModule); // ربط RabbitMQ للتبادل غير المتزامن app.connectMicroservice<MicroserviceOptions>({ transport: Transport.RMQ, options: { urls: ['amqp://localhost:5672'], queue: 'orders_queue', queueOptions: { durable: true }, }, });
await app.startAllMicroservices(); await app.listen(3000);}bootstrap();2. التنفيذ العملي: من نموذج البيانات إلى API
2.1 إنشاء حزمة مشتركة للأنواع
لتجنب تكرار الواجهات بين الخدمات، قم باستخراج الأنواع المشتركة في حزمة npm منفصلة (مثل @mycompany/shared-types). هذه ميزة رئيسية لـ TypeScript — مصدر واحد للحقيقة لجميع الخدمات.
// shared-types/src/dto/order.dto.tsexport interface CreateOrderDto { userId: string; productId: string; quantity: number; totalPrice: number;}
export interface OrderResponse { id: string; status: 'pending' | 'confirmed' | 'cancelled'; createdAt: Date;}2.2 تنفيذ Product Service (REST API)
خدمة كتالوج المنتجات. نستخدم TypeORM للعمل مع PostgreSQL ومزينات NestJS ل