وظائف Serverless بلغة TypeScript: المستوى المتقدم في AWS Lambda
\n\nأصبحت بنية Serverless المعيار الفعلي لبناء تطبيقات قابلة للتوسع واقتصادية. AWS Lambda هي واحدة من أشهر الخدمات لتنفيذ الوظائف بدون خادم. إذا تم إتقان بناء الجملة الأساسي والمحفزات (API Gateway, S3, DynamoDB)، فقد حان الوقت للتقنيات المتقدمة. في هذه المقالة، سننظر في الجوانب الرئيسية للتطوير الاحترافي لوظائف Lambda بلغة TypeScript: من تحسين البداية الباردة إلى التكامل مع VPC واستخدام الأنماط المعقدة.
\n\n1. تحسين البداية الباردة وإدارة الذاكرة
\n\nالبداية الباردة (cold start) هي العدو الرئيسي لأداء تطبيقات serverless. في TypeScript، تتفاقم هذه المشكلة بسبب مرحلة التجميع. سننظر في ثلاث طرق رئيسية للمكافحة.
\n\n1.1. تقليل حجم حزمة النشر
\nاستخدم esbuild للبناء بدلاً من tsc القياسي. يقوم بعملية tree-shaking والتصغير، مما يقلل حجم الحزمة بمقدار 5-10 مرات. مثال على التكوين لـ serverless.yml:
plugins:\n - serverless-esbuild\ncustom:\n esbuild:\n bundle: true\n minify: true\n sourcemap: false\n target: 'node18'\n exclude: ['aws-sdk'] # SDK موجود بالفعل في بيئة Lambda\n\n1.2. استخدام Provisioned Concurrency
\nللوظائف الحساسة للتأخير (مثل معالجة طلبات API)، قم بتكوين Provisioned Concurrency. هذا يحافظ على عدد محدد من الحاويات "الساخنة" قيد التشغيل باستمرار:
\n\nfunctions:\n apiHandler:\n handler: src/handler.apiHandler\n provisionedConcurrency: 5 # دائماً 5 حالات جاهزة\n\n1.3. تحسين الاستيرادات والكود
\nتجنب المكتبات "الثقيلة" داخل الوظيفة. على سبيل المثال، بدلاً من استيراد aws-sdk v3 بالكامل، استورد فقط العملاء المطلوبين:
// سيء: import * as AWS from 'aws-sdk';\n// جيد:\nimport { DynamoDBClient } from '@aws-sdk/client-dynamodb';\nimport { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';\n\n2. العمل مع طبقات Lambda والتبعيات
\n\nتسمح طبقات Lambda بإخراج الكود المشترك والتبعيات (مثل ORM، أدوات التحقق) خارج الوظيفة. هذا يسرع النشر ويقلل حجم كل حزمة فردية.
\n\n2.1. إنشاء طبقة بأدوات مساعدة مشتركة
\nيمكن أن يبدو هيكل المشروع كالتالي:
\n\nproject/\n├── layers/\n│ └── common/\n│ └── nodejs/\n│ ├── package.json\n│ └── node_modules/\n├── functions/\n│ ├── createUser.ts\n│ └── getUser.ts\n└── serverless.yml\n\nفي serverless.yml نقوم بتوصيل الطبقة:
layers:\n commonLibs:\n path: layers/common\n compatibleRuntimes:\n - nodejs18.x\nfunctions:\n createUser:\n handler: functions/createUser.handler\n layers:\n - { Ref: CommonLibsLambdaLayer }\n\n2.2. كتابة الأنواع للطبقات
\nلكي "يرى" TypeScript الأنواع من الطبقة، قم بإنشاء tsconfig.json مع المسارات:
{\n "compilerOptions": {\n "paths": {\n "@common/*": ["layers/common/nodejs/*"]\n }\n }\n}\n\nالآن يمكنك الكتابة في الوظيفة:
\nimport { validateEmail } from '@common/validators';\n\n3. العمل مع VPC والأمان
\n\nوظائف Lambda التي تعمل داخل VPC تفقد الوصول إلى الإنترنت العام (إذا لم يتم تكوين NAT Gateway). هذا أمر بالغ الأهمية للاتصال بـ RDS أو ElastiCache أو APIs الخاصة.
\n\n3.1. تكوين Lambda في VPC
\nالتكوين عبر serverless.yml:
provider:\n vpc:\n securityGroupIds:\n - sg-12345\n subnetIds:\n - subnet-abc\n - subnet-def\n\nfunctions:\n dbHandler:\n handler: src/db.handler\n vpc: true # يرث إعدادات المزود\n\n3.2. نمط "Thin Handler" للاتصالات
\nقراءة