إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
يغطي هذا المرجع كيفية تطوير دالات Azure باستخدام JavaScript وTypeScript باستخدام @azure/functions حزمة npm. للحصول على نظرة عامة عامة على مفاهيم دالات Azure المشتركة عبر جميع اللغات، راجع مرجع المطورين دالات Azure.
| Resource | رابط |
|---|---|
| أنشئ أول وظيفة جافاسكريبت لك | تعليمة Visual Studio برمجيةCLI/ |
| أنشئ أول وظيفة TypeScript لك | تعليمة Visual Studio برمجيةCLI/ |
| السيناريوهات والعينات | جافا سكريبت/تايب سكريبت |
| مرجع واجهة برمجة التطبيقات |
@azure/functions واجهة برمجة التطبيقات |
Note
تعرض هذه المقالة محتوى لإصدار نموذج برمجة معين بناء على المحدد في أعلى الصفحة. النسخة التي تختارها يجب أن تتطابق مع نسخة حزمة npm الخاصة بك @azure/functions . لا يمكنك خلط وظائف v3 و v4 في نفس التطبيق. إذا لم يكن لديك الحزمة في جهازك package.json، فإن الإعداد الافتراضي هو v3.
نموذج البرمجة
يدعم دالات Azure Node.js نسختين من نماذج البرمجة. المشاريع الجديدة يجب أن تستخدم الإصدار الرابع.
| الميزة | v4 (موصى به) | v3 |
|---|---|---|
| حاله | GA | GA (الصيانة) |
@azure/functions الحزمة |
4.x | 3.x |
| تسجيل الوظائف | الكود المركزة (app.http(), app.timer()) |
المعتمد على الملفات (function.json) |
| هيكل الملفات | مرن | ثابت (مجلد واحد لكل وظيفة) |
| إصدار وقت تشغيل الوظائف | 4.25+ | 4.x |
| Node.js النسخ | 24.x، 22.x | 24.x، 22.x |
في نموذج البرمجة Node.js v4، تقوم بتسجيل الدوال عن طريق استيراد الكائن app من @azure/functions واستدعاء طرق خاصة بالمشغل. الوظائف محددة مباشرة في الكود الخاص بك من خلال هيكل ملفات مرن. كل وظيفة لها محفز واحد يبدأ تنفيذها ويمكن أن تحتوي أيضا على ربطات، وهي اتصالات إعلانية مع خدمات أخرى لقراءة بيانات الإدخال أو كتابة بيانات الإخراج. لمزيد من المعلومات، راجع المحفزات والروابط.
في نموذج v4، أنت:
- وظائف السجلات باستخدام طرق خاصة بالمشغلات مثل
app.http()،app.timer()، وapp.storageQueue(). - ادخل إدخال الزناد كأول وسيط إلى معالجك (على سبيل المثال،
HttpRequest). - أعيد الإخراج الأساسي مباشرة من دالة المعالج.
- أستخدم
context.extraInputs.get()القراءة من إعدادات إدخال إضافية مثل مخزن البيانات الثنائية الكبيرة. - أستخدم
context.extraOutputs.set()الكتابة إلى روابط إضافية مثل قوائم الانتظار. - كل وظيفة لها مشغل واحد فقط، لكنها يمكن أن تحتوي على عدة مدخلات ومخرجات إضافية.
- يمكنك تخزين البيانات مؤقتا في المتغيرات العامة لإعادة استخدامها عبر الاستدعاءات، لكن لا تعتمد على هذه الحالة للاستمرار. يمكن لوقت التشغيل إعادة تدوير العامل في أي وقت.
في نموذج البرمجة Node.js v3، تعرف كل وظيفة باستخدام function.json ملف تكوين وكود جافاسكريبت أو تايب سكريبت المقابل. تنظم الوظائف في مجلدات منفصلة مع هياكل ملفات محددة. كل وظيفة لها محفز واحد يبدأ تنفيذها ويمكن أن تحتوي أيضا على ربطات، وهي اتصالات إعلانية مع خدمات أخرى لقراءة بيانات الإدخال أو كتابة بيانات الإخراج. لمزيد من المعلومات، راجع المحفزات والروابط.
في نموذج v3، أنت:
- تعريف المحفزات والقيود في ملف
function.json. الاستخدامdirection: "in"للمدخلات والمخرجاتdirection: "out". - ادخل إدخال المحفز كوسيطة ثانية إلى معالجك، أو اقرأه من
context.bindings. - اضبط المخرجات عن طريق تعيين قيم ل
context.bindings(على سبيل المثال،context.bindings.outputQueue). بالنسبة ل HTTP، استخدمcontext.res. - تتطلب مشاريع TypeScript خاصية
scriptFileفي تشيرfunction.jsonإلى ملف جافاسكريبت المترجم. - كل وظيفة لها مشغل واحد بالضبط، لكنها يمكن أن تحتوي على عدة روابط إدخال وإخراج.
- يمكنك تخزين البيانات مؤقتا في المتغيرات العامة لإعادة استخدامها عبر الاستدعاءات، لكن لا تعتمد على هذه الحالة للاستمرار. يمكن لوقت التشغيل إعادة تدوير العامل في أي وقت.
أمثلة
إليك دالة بسيطة تستجيب لطلب HTTP:
const { app } = require('@azure/functions');
app.http('httpTrigger', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: async (request, context) => {
const name = request.query.get('name') || 'World';
context.log('HTTP trigger function processed a request.');
return { body: `Hello, ${name}!` };
}
});
المثال التالي غير HTTP يستخدم مشغل المؤقت:
const { app } = require('@azure/functions');
app.timer('cleanupTimer', {
schedule: '0 */5 * * * *',
handler: async (myTimer, context) => {
context.log('Timer trigger function ran at', new Date().toISOString());
}
});
المثال التالي يظهر مشغل HTTP مع ربط إخراج الطابور:
const { app, output } = require('@azure/functions');
const queueOutput = output.storageQueue({
queueName: 'work-items',
connection: 'AzureWebJobsStorage'
});
app.http('submitWorkItem', {
methods: ['POST'],
extraOutputs: [queueOutput],
handler: async (request, context) => {
const body = await request.json();
context.extraOutputs.set(queueOutput, JSON.stringify(body));
return { status: 202, jsonBody: { accepted: true } };
}
});
إليك دالة بسيطة تستجيب لطلب HTTP:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
module.exports = async function (context, req) {
const name = (req.query.name || (req.body && req.body.name)) || 'World';
context.log('HTTP trigger function processed a request.');
context.res = {
body: `Hello, ${name}!`
};
};
المثال التالي غير HTTP يستخدم مشغل المؤقت:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
}
]
}
module.exports = async function (context, myTimer) {
context.log('Timer trigger function ran at', new Date().toISOString());
};
المثال التالي يظهر مشغل HTTP مع ربط إخراج الطابور:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["post"]
},
{
"type": "queue",
"direction": "out",
"name": "workItems",
"queueName": "work-items",
"connection": "AzureWebJobsStorage"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
module.exports = async function (context, req) {
const payload = req.body || {};
context.bindings.workItems = JSON.stringify(payload);
context.res = {
status: 202,
body: { accepted: true }
};
};
بناء تطبيق الوظائف الخاص بك
يغطي هذا القسم المكونات الأساسية لإنشاء وهيكلة تطبيق وظيفة العقدة الخاص بك، بما في ذلك @azure/functions المكتبة، هيكل المشروع، وإدارة الحزم.
المكتبة @azure/functions
@azure/functions توفر مكتبة TypeScript/JavaScript الأنواع الأساسية والدوال التي تستخدمها للتفاعل مع وقت تشغيل دالات Azure. لرؤية جميع الأنواع والطرق المتاحة، قم بزيارة @azure/functions واجهة برمجة التطبيقات (API).
يمكن لكود الوظيفة الخاص بك أن يستخدم @azure/functions ل:
- وظائف السجلات وتعريف المحفزات (نموذج v4).
- الوصول إلى بيانات إدخال المحفز ذات النوع القوي (على سبيل المثال،
HttpRequest،Timer). - أنشئ قيم مخرجات مكتوبة (مثل
HttpResponseInit). - تفاعل مع السياق وبيانات الربط التي توفرها وقت التشغيل.
إذا كنت تستخدمها @azure/functions في تطبيقك، ضمه في تبعيات مشروعك:
{
"dependencies": {
"@azure/functions": "^4.0.0"
}
}
Note
تحدد المكتبة @azure/functions سطح البرمجة ل Node.js دالات Azure، لكنها ليست حزمة تطوير تطوير متعددة الأغراض. استخدمه تحديدا لتأليف وتشغيل الوظائف ضمن وقت تشغيل دالات Azure.
تكوين TypeScript
للحصول على أفضل تجربة تطوير ل TypeScript، تأكد tsconfig.json من تضمين التكوين المناسب:
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "dist",
"rootDir": ".",
"sourceMap": true,
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
هيكل المجلد
يتطلب مشروع جافاسكريبت هيكل المجلدات الموضح في المثال التالي:
<project_root>/
| - .vscode/
| - node_modules/
| - myFirstFunction/
| | - index.js
| | - function.json
| - mySecondFunction/
| | - index.js
| | - function.json
| - .funcignore
| - host.json
| - local.settings.json
| - package.json
يمكن أن يحتوي مجلد المشروع الرئيسي، <project_root>، على الملفات التالية:
- .vscode/: (اختياري) يحتوي على تكوين تعليمة Visual Studio برمجية المخزن. لمعرفة المزيد، راجع تعليمة Visual Studio برمجية الإعدادات.
- myFirstFunction/function.json: يحتوي على تكوين لمشغل الوظيفة ومدخلاتها ومخرجاتها. يحدد اسم الدليل اسم الدالة الخاصة بك.
- myFirstFunction/index.js: يخزن رمز الوظيفة الخاص بك. لتغيير مسار الملف الافتراضي هذا، راجع استخدام scriptFile.
- .funcignore: (اختياري) يعلن الملفات التي لا ينبغي نشرها على Azure. عادة ما يحتوي هذا الملف على .vscode/ لتجاهل إعداد المحرر لديك، واختبار/ لتجاهل حالات الاختبار، وlocal.settings.json لمنع نشر إعدادات التطبيقات المحلية.
- host.json: يحتوي على خيارات التكوين التي تؤثر على جميع الوظائف في مثيل تطبيق الوظائف. يتم نشر هذا الملف على Azure. لا يتم دعم جميع الخيارات عند التشغيل محليًا. لمعرفة المزيد، راجع host.json.
- local.settings.json: يستخدم لتخزين إعدادات التطبيق وسلاسل الاتصال عند التشغيل محليا. هذا الملف لا يتم نشره على Azure. لمعرفة المزيد، راجع local.settings.file.
- package.json: يحتوي على خيارات تكوين مثل قائمة تبعيات الحزم، نقطة الدخول الرئيسية، والسكريبتات النصية.
يتبع مشروع جافاسكريبت هيكل المجلدات الموصى به في المثال التالي:
<project_root>/
| - .vscode/
| - node_modules/
| - src/
| | - functions/
| | | - myFirstFunction.js
| | | - mySecondFunction.js
| - test/
| | - functions/
| | | - myFirstFunction.test.js
| | | - mySecondFunction.test.js
| - .funcignore
| - host.json
| - local.settings.json
| - package.json
يمكن أن يحتوي مجلد المشروع الرئيسي، <project_root>، على الملفات التالية:
- .vscode/: (اختياري) يحتوي على تكوين تعليمة Visual Studio برمجية المخزن. لمعرفة المزيد، راجع تعليمة Visual Studio برمجية الإعدادات.
- src/functions/: الموقع الافتراضي لجميع الوظائف والمشغلات والروابط ذات الصلة.
- test/: (اختياري) يحتوي على حالات الاختبار لتطبيق الوظائف الخاص بك.
- .funcignore: (اختياري) يعلن الملفات التي لا ينبغي نشرها على Azure. عادة ما يحتوي هذا الملف على .vscode/ لتجاهل إعداد المحرر لديك، واختبار/ لتجاهل حالات الاختبار، وlocal.settings.json لمنع نشر إعدادات التطبيقات المحلية.
- host.json: يحتوي على خيارات التكوين التي تؤثر على جميع الوظائف في مثيل تطبيق الوظائف. يتم نشر هذا الملف على Azure. لا يتم دعم جميع الخيارات عند التشغيل محليًا. لمعرفة المزيد، راجع host.json.
- local.settings.json: يستخدم لتخزين إعدادات التطبيق وسلاسل الاتصال عند التشغيل محليا. هذا الملف لا يتم نشره على Azure. لمعرفة المزيد، راجع local.settings.file.
- package.json: يحتوي على خيارات تكوين مثل قائمة تبعيات الحزم، نقطة الدخول الرئيسية، والسكريبتات النصية.
إدارة الحزم
إدارة الحزم الفعالة أمر بالغ الأهمية لمشاريع Node.js دالات Azure. يغطي هذا القسم إدارة التبعيات، وتكوين الحزم، وأفضل الممارسات للحفاظ على تبعيات تطبيقات الوظائف الخاصة بك.
إدارة التبعيات
جميع المشاريع Node.js دالات Azure تستخدم npm لإدارة الحزم. ملفك package.json يحدد تكوين المشروع، والتبعيات، والسكريبتات اللازمة لبناء وتشغيل وظائفك.
هيكل package.json الأساسي:
{
"name": "my-functions-app",
"version": "1.0.0",
"description": "Azure Functions Node.js app",
"main": "src/index.js",
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"prestart": "npm run build",
"start": "func start",
"test": "jest"
},
"dependencies": {
"@azure/functions": "^4.0.0"
},
"devDependencies": {
"@azure/functions-core-tools": "^4.0.4670",
"@types/node": "^18.0.0",
"typescript": "^4.0.0",
"jest": "^29.0.0"
}
}
تبعيات وقت التشغيل مقابل التطوير
افصل تبعياتك بشكل مناسب:
تبعيات وقت التشغيل (dependencies):
-
@azure/functions: مكتبة دالات Azure الأساسية - مكتبات منطق الأعمال (lodash، axios، والحزم المشابهة)
- برامج تشغيل قواعد البيانات (mongodb، mssql، وحزم مشابهة)
- حزم Azure SDK (@azure/تخزين-blob، @azure/cosmosوحزم مشابهة)
تبعيات التطوير (devDependencies):
- مترجم وتعريفات الأنواع في TypeScript
- أطر اختبار (Jest, Mocha)
- أدوات البناء واللينتر
- دالات Azure Core Tools (for local development)
الحزم الخاصة ب TypeScript
بالنسبة لمشاريع TypeScript، قم بتضمين هذه التبعيات الأساسية في التطوير:
{
"devDependencies": {
"@types/node": "^18.0.0",
"typescript": "^4.0.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0"
}
}
الأمان والتحديثات
قم بتحديث تبعياتك بانتظام لمعالجة الثغرات الأمنية:
# Check for outdated packages
npm outdated
# Update packages
npm update
# Audit for security issues
npm audit
npm audit fix
التشغيل والتصحيح
يغطي هذا القسم التطوير المحلي، وتقنيات التصحيح، واستراتيجيات الاختبار Node.js دالات Azure.
إعداد التنمية المحلية
المتطلبات المسبقه:
- Node.js الإصدار 18.x أو 20.x
- دالات Azure Core Tools v4.x
- Azure CLI (اختياري)
خطوات الإعداد:
تبعيات التثبيت:
npm installمشاريع بناء TypeScript:
npm run buildابدأ وقت التشغيل المحلي:
npm start # or directly: func start
تكوين البيئة
قم بتكوين بيئة local.settings.jsonالتطوير المحلية باستخدام :
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "node",
"NODE_ENV": "development",
"CUSTOM_ENV_VARIABLE": "local-value"
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "*",
"CORSCredentials": false
}
}
Debugging
تصحيح أخطاء تعليمة Visual Studio برمجية:
إنشاء .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Node Functions",
"type": "node",
"request": "attach",
"port": 9229,
"preLaunchTask": "func: host start"
}
]
}
إنشاء .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"type": "func",
"label": "func: host start",
"command": "host start",
"problemMatcher": "$func-node-watch",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}"
}
}
]
}
تصحيح أخطاء سطر الأوامر:
# Start with debugging enabled
func start --p <port>
# For TypeScript, ensure you build first
npm run build
func start --p 9229
Deployment
يغطي هذا القسم استراتيجيات النشر، وتكامل CI/CD، وأفضل ممارسات الإنتاج ل Node.js دالات Azure.
أساليب التوزيع
1. نشر تعليمة Visual Studio برمجية:
- تثبيت إضافة دالات Azure.
- انقر بزر الفأرة الأيمن على تطبيق الوظائف الخاص بك في لوحة Azure.
- حدد Deploy to Function App.
2. دالات Azure Core Tools:
# Deploy to Azure
func azure functionapp publish <FunctionAppName>
# Deploy with custom settings
func azure functionapp publish <FunctionAppName> --build local --publish-local-settings
3. نشر Azure CLI:
# Deploy from local folder
az functionapp deployment source config-zip \
--resource-group <ResourceGroupName> \
--name <FunctionAppName> \
--src <PathToZipFile>
تكوين الإنتاج
إعدادات التطبيق في Azure:
تكوين متغيرات البيئة للإنتاج:
-
WEBSITE_NODE_DEFAULT_VERSION: اضبط على~18أو~20. -
FUNCTIONS_WORKER_RUNTIME: ضبطه علىnode. - سلاسل الاتصال ومفاتيح واجهة برمجة التطبيقات كإعدادات تطبيقات آمنة.
-
NODE_ENV: ضبطه علىproduction.
المشغلات وعمليات الربط
يستخدم دالات Azure triggers لبدء تنفيذ الدوال وbindings لربط كودك بخدمات أخرى مثل التخزين، الطوابير، وقواعد البيانات. في نموذج البرمجة Node.js، تعلن عن الروابط بشكل مختلف حسب إصدار النموذج.
يوجد نوعان رئيسيان من الربطات:
- المحفزات (المدخل الذي يبدأ الوظيفة)
- المدخلات والمخرجات (مصادر بيانات إضافية أو وجهات أخرى)
لمزيد من المعلومات حول المحفزات والروابط المتاحة، انظر Triggers and Bindings في دالات Azure.
مثال: مشغل مؤقت مع إدخال كتلة
يتم تفعيل هذه الوظيفة كل 10 دقائق، وتقرأ من Blob باستخدام مدخلات إضافية، وتسجل محتوى البلوب.
const { app, input } = require('@azure/functions');
let CACHED_BLOB_DATA = null;
const blobInput = input.storageBlob({
connection: 'BLOB_CONNECTION_SETTING',
path: 'mycontainer/myblob.txt'
});
app.timer('TimerTriggerWithBlob', {
schedule: '0 */10 * * * *',
extraInputs: [blobInput],
handler: async (myTimer, context) => {
if (CACHED_BLOB_DATA === null) {
// Read blob content and cache it
CACHED_BLOB_DATA = context.extraInputs.get(blobInput);
context.log(`Blob content cached: ${CACHED_BLOB_DATA?.substring(0, 100)}...`);
}
context.log(`Timer function executed at: ${new Date().toISOString()}`);
context.log(`Using cached data of length: ${CACHED_BLOB_DATA?.length || 0}`);
}
});
يتم تفعيل هذه الوظيفة كل 10 دقائق، وتقرأ من Blob باستخدام إعدادات الربط (lidings)، وتسجل محتوى الblob.
{
"scriptFile": "index.js",
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */10 * * * *"
},
{
"name": "blobInput",
"type": "blob",
"direction": "in",
"path": "mycontainer/myblob.txt",
"connection": "AzureWebJobsStorage"
}
]
}
let CACHED_BLOB_DATA = null;
module.exports = async function (context, myTimer) {
if (CACHED_BLOB_DATA === null) {
// Read blob content and cache it
CACHED_BLOB_DATA = context.bindings.blobInput;
context.log(`Blob content cached: ${CACHED_BLOB_DATA?.substring(0, 100)}...`);
}
context.log(`Timer function executed at: ${new Date().toISOString()}`);
context.log(`Using cached data of length: ${CACHED_BLOB_DATA?.length || 0}`);
};
مثال: مشغل HTTP مع إخراج الطابور
يتم تفعيل هذه الوظيفة عند طلب HTTP، وتكتب رسالة إلى قائمة تخزين التخزين، وتعيد استجابة HTTP.
const { app, output } = require('@azure/functions');
const queueOutput = output.storageQueue({
connection: 'AzureWebJobsStorage',
queueName: 'myqueue'
});
app.http('httpTriggerWithQueue', {
methods: ['GET', 'POST'],
extraOutputs: [queueOutput],
handler: async (request, context) => {
const name = request.query.get('name') || 'World';
const message = {
id: context.invocationId,
name: name,
timestamp: new Date().toISOString()
};
// Write to queue output
context.extraOutputs.set(queueOutput, JSON.stringify(message));
context.log(`Message sent to queue: ${JSON.stringify(message)}`);
return {
body: `Hello, ${name}! Message queued successfully.`
};
}
});
يتم تفعيل هذه الوظيفة عند طلب HTTP، وتكتب رسالة إلى قائمة تخزين التخزين، وتعيد استجابة HTTP.
{
"scriptFile": "index.js",
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"type": "queue",
"direction": "out",
"name": "outputQueue",
"queueName": "myqueue",
"connection": "AzureWebJobsStorage"
}
]
}
module.exports = async function (context, req) {
const name = (req.query.name || (req.body && req.body.name)) || 'World';
const message = {
id: context.invocationId,
name: name,
timestamp: new Date().toISOString()
};
// Write to queue output
context.bindings.outputQueue = JSON.stringify(message);
context.log(`Message sent to queue: ${JSON.stringify(message)}`);
return {
status: 200,
body: `Hello, ${name}! Message queued successfully.`
};
};
app
triggerتوفر الكائنات و inputو و output التي تم تصديرها بواسطة @azure/functions الوحدة النمطية أساليب خاصة بالنوع لمعظم الأنواع. بالنسبة لجميع الأنواع غير المدعومة، generic يتم توفير أسلوب للسماح لك بتحديد التكوين يدويا.
generic يمكن أيضا استخدام الأسلوب إذا كنت تريد تغيير الإعدادات الافتراضية التي يوفرها أسلوب خاص بنوع معين.
المثال التالي هو دالة HTTP بسيطة يتم تشغيلها باستخدام أساليب عامة بدلا من أساليب خاصة بالنوع.
const { app, output, trigger } = require("@azure/functions");
app.generic("helloWorld1", {
trigger: trigger.generic({
type: "httpTrigger",
methods: ["GET", "POST"],
}),
return: output.generic({
type: "http",
}),
handler: async (request, context) => {
context.log(`Http function processed request for url "${request.url}"`);
return { body: `Hello, world!` };
},
});
::: نهاية المنطقة
سياق الاستدعاء
كل استدعاء لوظيفتك يحصل على كائن استدعاء context . استخدم هذا الكائن لقراءة المدخلات، وتعيين المخرجات، والكتابة في السجلات، والوصول إلى بيانات وصفية متنوعة. في نموذج v3، تقوم دائما بتمرير كائن السياق كأول وسيط إلى معالجك.
يتضمن الكائن context الخصائص التالية:
| Property | Description |
|---|---|
invocationId |
معرف استدعاء الدالة الحالية. |
executionContext |
راجع سياق التنفيذ. |
bindings |
انظر الروابط. |
bindingData |
بيانات وصفية حول إدخال المحفز لهذا الاستدعاء، باستثناء القيمة نفسها. على سبيل المثال، يحتوي مشغل مركز الأحداث على enqueuedTimeUtc خاصية . |
traceContext |
سياق التتبع الموزع. لمزيد من المعلومات، راجع Trace Context. |
bindingDefinitions |
تكوين المدخلات والمخرجات الخاصة بك، كما هو محدد في function.json. |
req |
راجع طلب HTTP. |
res |
راجع استجابة HTTP. |
context.executionContext
يحتوي context.executionContext الكائن على الخصائص التالية:
| Property | Description |
|---|---|
invocationId |
معرف استدعاء الدالة الحالية. |
functionName |
اسم الدالة التي تستدعيها. يحدد اسم المجلد الذي يحتوي على function.json الملف اسم الدالة. |
functionDirectory |
المجلد الذي يحتوي على function.json الملف. |
retryContext |
راجع سياق إعادة المحاولة. |
context.executionContext.retryContext
يحتوي context.executionContext.retryContext الكائن على الخصائص التالية:
| Property | Description |
|---|---|
retryCount |
رقم يمثل محاولة إعادة المحاولة الحالية. |
maxRetryCount |
الحد الأقصى لعدد مرات إعادة محاولة تنفيذ. تعني قيمة -1 إعادة المحاولة إلى أجل غير مسمى. |
exception |
الاستثناء الذي تسبب في إعادة المحاولة. |
context.bindings
استخدم الكائن context.bindings لقراءة المدخلات أو تعيين المخرجات. المثال التالي هو مشغل طابور التخزين الذي يستخدم context.bindings لنسخ مدخل كتلة تخزين إلى مخرج كتلة تخزين. يتم استبدال {queueTrigger} محتوى رسالة قائمة الانتظار باسم الملف المراد نسخه، بمساعدة تعبير ملزم.
{
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in",
"connection": "storage_APPSETTING",
"queueName": "helloworldqueue"
},
{
"name": "myInput",
"type": "blob",
"direction": "in",
"connection": "storage_APPSETTING",
"path": "helloworld/{queueTrigger}"
},
{
"name": "myOutput",
"type": "blob",
"direction": "out",
"connection": "storage_APPSETTING",
"path": "helloworld/{queueTrigger}-copy"
}
module.exports = async function (context, myQueueItem) {
const blobValue = context.bindings.myInput;
context.bindings.myOutput = blobValue;
};
context.done
الأسلوب context.done مهمل. قبل أن يدعم دالات Azure الدوال غير المتزامنة، كنت تشير إلى أن وظيفتك قد أنجزت عن طريق استدعاء context.done():
module.exports = function (context, request) {
context.log("this pattern is now deprecated");
context.done();
};
قم بإزالة النداء إلى context.done(). ضع علامة على وظيفتك كغير متزامنة حتى تعيد وعدا (حتى لو لم تكن تفعل await شيئا). بمجرد انتهاء الدالة الخاصة بك (بمعنى آخر، يحل الوعد الذي تم إرجاعه)، يعرف نموذج v3 أن وظيفتك قد انتهت.
module.exports = async function (context, request) {
context.log("you don't need context.done or an awaited call");
};
كل استدعاء لوظيفتك يحصل على كائن استدعاء context . يحتوي هذا الكائن على معلومات عن استدعاءك وطرق التسجيل. في نموذج v4، عادة ما تمرر الكائن context كوسيطة ثانية إلى معالجك.
تشمل الفئة InvocationContext الخصائص التالية:
| Property | Description |
|---|---|
invocationId |
معرف استدعاء الدالة الحالية. |
functionName |
اسم الدالة |
extraInputs |
يستخدم للحصول على قيم المدخلات الإضافية. لمزيد من المعلومات، راجع المدخلات والمخرجات الإضافية. |
extraOutputs |
يستخدم لتعيين قيم المخرجات الإضافية. لمزيد من المعلومات، راجع المدخلات والمخرجات الإضافية. |
retryContext |
راجع سياق إعادة المحاولة. |
traceContext |
سياق التتبع الموزع. لمزيد من المعلومات، راجع Trace Context. |
triggerMetadata |
بيانات التعريف حول إدخال المشغل لهذا الاستدعاء، وليس بما في ذلك القيمة نفسها. على سبيل المثال، يحتوي مشغل مركز الأحداث على enqueuedTimeUtc خاصية . |
options |
الخيارات المستخدمة عند تسجيل الوظيفة بعد التحقق منها وتحديد الإعدادات الافتراضية بشكل صريح. |
سياق إعادة المحاولة
يحتوي retryContext الكائن على الخصائص التالية:
| Property | Description |
|---|---|
retryCount |
رقم يمثل محاولة إعادة المحاولة الحالية. |
maxRetryCount |
الحد الأقصى لعدد مرات إعادة محاولة تنفيذ. تعني قيمة -1 إعادة المحاولة إلى أجل غير مسمى. |
exception |
الاستثناء الذي تسبب في إعادة المحاولة. |
لمزيد من المعلومات، راجع retry-policies.
Logging
في دالات Azure، استخدم context.log() لكتابة السجلات. دالات Azure يتكامل مع Azure Application Insights لالتقاط سجلات تطبيقات الوظائف بشكل أفضل. يوفر Application Insights، جزء من Azure Monitor، وسائل لجمع وعرض بصري وتحليل سجلات التطبيقات ومخرجات التتبع الخاصة بك. لمعرفة المزيد، راجع monitoring دالات Azure.
Note
إذا استخدمت طريقة Node.js console.log البديلة، يتم تتبع سجلات مستوى التطبيق لكنها لا ترتبط بأي وظيفة محددة. يستخدم context للتسجيل بدلا console من أن ترتبط جميع السجلات بدالة محددة.
يكتب المثال التالي سجلا على مستوى "المعلومات" الافتراضي، بما في ذلك معرف استدعاء:
context.log(`Something has happened. Invocation ID: "${context.invocationId}"`);
مستويات السجل
بالإضافة إلى الطريقة الافتراضية context.log ، استخدم الطرق التالية لكتابة السجلات على مستويات محددة:
| Method | Description |
|---|---|
context.log.error() |
تكتب حدث على مستوى الخطأ على السجلات. |
context.log.warn() |
تكتب حدث مستوى التحذير على السجلات. |
context.log.info() |
كتابة حدث على مستوى المعلومات إلى السجلات. |
context.log.verbose() |
يكتب حدثا على مستوى التتبع إلى السجلات. |
| Method | Description |
|---|---|
context.trace() |
يكتب حدثا على مستوى التتبع إلى السجلات. |
context.debug() |
يكتب حدثا على مستوى تتبع الأخطاء إلى السجلات. |
context.info() |
كتابة حدث على مستوى المعلومات إلى السجلات. |
context.warn() |
تكتب حدث مستوى التحذير على السجلات. |
context.error() |
تكتب حدث على مستوى الخطأ على السجلات. |
تكوين مستوى السجل
تمكنك الدوال من تحديد مستوى العتبة لتتبع وعرض السجلات. لتعيين الحد، استخدم الخاصية logging.logLevel في host.json الملف. تتيح لك هذه الخاصية تحديد مستوى افتراضي لجميع الدوال أو عتبة لكل دالة فردية. لمزيد من المعلومات، راجع كيفية تكوين مراقبة دالات Azure.
تعقب البيانات المخصصة
بشكل افتراضي، يكتب دالات Azure الإخراج كتتبع إلى Application Insights. لمزيد من التحكم، استخدم Application Insights Node.js SDK لإرسال سجلات ومؤشرات وتبعيات مخصصة إلى مثيل Application Insights الخاص بك.
Note
قد تتغير الطرق في رؤى التطبيقات Node.js SDK مع مرور الوقت. قد تكون هناك اختلافات نحوية بسيطة من الأمثلة المعروضة هنا. للحصول على أحدث أمثلة استخدام واجهة برمجة التطبيقات، راجع وثائق Application Insights Node.js SDK.
للتتبع الموزع في نموذج البرمجة Node.js v4، استخدم الحزمة @azure/functions-opentelemetry-instrumentation بدلا من Application Insights SDK. توفر هذه الحزمة أجهزة تلقائية قائمة على OpenTelemetry لنظام دالات Azure. لمزيد من المعلومات، راجع OpenTelemetry دالات Azure Instrumentation لمستودع Node.js GitHub.
const appInsights = require("applicationinsights");
appInsights.setup();
const client = appInsights.defaultClient;
module.exports = async function (context, request) {
// Use this with 'tagOverrides' to correlate custom logs to the parent function invocation.
var operationIdOverride = {
"ai.operation.id": context.traceContext.traceparent,
};
client.trackEvent({
name: "my custom event",
tagOverrides: operationIdOverride,
properties: { customProperty2: "custom property value" },
});
client.trackException({
exception: new Error("handled exceptions can be logged with this method"),
tagOverrides: operationIdOverride,
});
client.trackMetric({
name: "custom metric",
value: 3,
tagOverrides: operationIdOverride,
});
client.trackTrace({
message: "trace message",
tagOverrides: operationIdOverride,
});
client.trackDependency({
target: "http://dbname",
name: "select customers proc",
data: "SELECT * FROM Customers",
duration: 231,
resultCode: 0,
success: true,
dependencyTypeName: "ZSQL",
tagOverrides: operationIdOverride,
});
client.trackRequest({
name: "GET /customers",
url: "http://myserver/customers",
duration: 309,
resultCode: 200,
success: true,
tagOverrides: operationIdOverride,
});
};
المعلمة tagOverrides تعين operation_Id لمعرف استدعاء الوظيفة. يتيح لك هذا الإعداد ربط جميع السجلات المولدة تلقائيا والمخصصة لاستدعاء وظيفة معينة.
مشغلات HTTP
تستخدم مشغلات HTTP والإخطار على الويب كائنات الطلب والاستجابة لتمثيل رسائل HTTP.
تستخدم HttpRequest مشغلات HTTP والإخطار على الويب والكائنات HttpResponse لتمثيل رسائل HTTP. تمثل الفئات مجموعة فرعية من معيار الجلب ، باستخدام حزمة Node.jsundici .
طلب HTTP
الوصول إلى الطلب بعدة طرق:
كوسيطة ثانية لدالتك:
module.exports = async function (context, request) { context.log(`Http function processed request for url "${request.url}"`);
من الخاصية
context.req:module.exports = async function (context, request) { context.log(`Http function processed request for url "${context.req.url}"`);
من الروابط المدخلة المسماة: يعمل هذا الخيار بنفس طريقة أي ربط غير HTTP. يجب أن يتطابق اسم الربط في
function.jsonمع المفتاح الموجود علىcontext.bindingsأو "request1" في المثال التالي:{ "name": "request1", "type": "httpTrigger", "direction": "in", "authLevel": "anonymous", "methods": ["get", "post"] }module.exports = async function (context, request) { context.log(`Http function processed request for url "${context.bindings.request1.url}"`);
يحتوي HttpRequest الكائن على الخصائص التالية:
| Property | Type | Description |
|---|---|---|
method |
string |
أسلوب طلب HTTP المستخدم لاستدعاء هذه الدالة. |
url |
string |
طلب عنوان URL. |
headers |
Record<string, string> |
عناوين طلب HTTP. هذا الكائن حساس لحالة الأحرف. استخدمها request.getHeader('header-name') بدلا من ذلك، وهذا غير حساس للحروف. |
query |
Record<string, string> |
مفاتيح وقيم معلمات سلسلة الاستعلام من عنوان URL. |
params |
Record<string, string> |
مفاتيح وقيم معلمات المسار. |
user |
HttpRequestUser \| null |
كائن يمثل المستخدم الذي قام بتسجيل الدخول، إما من خلال مصادقة الوظائف أو مصادقة SWA أو القيمة الخالية عند عدم تسجيل دخول أي مستخدم من هذا القبيل. |
body |
Buffer \| string \| any |
إذا كان نوع الوسائط هو "application/octet-stream" أو "multipart/*"، body فهو مخزن مؤقت. إذا كانت القيمة عبارة عن سلسلة قادرة على تحليل JSON، body فهي الكائن الذي تم تحليله. خلاف ذلك، body هو سلسلة. |
rawBody |
string |
النص الأساسي كسلسلة. على الرغم من الاسم، لا ترجع هذه الخاصية مخزنا مؤقتا. |
bufferBody |
Buffer |
النص الأساسي كمخزن مؤقت. |
يمكنك الوصول إلى الطلب كأول وسيط إلى معالجك لوظيفة HTTP مفعلة.
async (request, context) => {
context.log(`Http function processed request for url "${request.url}"`);
يحتوي HttpRequest الكائن على الخصائص التالية:
| Property | Type | Description |
|---|---|---|
method |
string |
أسلوب طلب HTTP المستخدم لاستدعاء هذه الدالة. |
url |
string |
طلب عنوان URL. |
headers |
Headers |
عناوين طلب HTTP. |
query |
URLSearchParams |
مفاتيح وقيم معلمات سلسلة الاستعلام من عنوان URL. |
params |
Record<string, string> |
مفاتيح وقيم معلمات المسار. |
user |
HttpRequestUser \| null |
كائن يمثل المستخدم الذي قام بتسجيل الدخول، إما من خلال مصادقة الوظائف أو مصادقة SWA أو القيمة الخالية عند عدم تسجيل دخول أي مستخدم من هذا القبيل. |
body |
ReadableStream \| null |
النص الأساسي كتدفق قابل للقراءة. |
bodyUsed |
boolean |
قيمة منطقية تشير إلى ما إذا كان النص قد تمت قراءته بالفعل. |
للوصول إلى نص الطلب أو الرد، استخدم الطرق التالية:
| Method | نوع الإرجاع |
|---|---|
arrayBuffer() |
Promise<ArrayBuffer> |
blob() |
Promise<Blob> |
formData() |
Promise<FormData> |
json() |
Promise<unknown> |
text() |
Promise<string> |
Note
يمكنك تشغيل وظائف الجسم مرة واحدة فقط. تحل المكالمات اللاحقة باستخدام سلاسل فارغة أو مصفوفات مصفوفات.
استجابة HTTP
يمكنك ضبط الاستجابة بعدة طرق. على سبيل المثال، يمكنك استخدام:
تعيين الخاصية
context.res:module.exports = async function (context, request) { context.res = { body: `Hello, world!` };
إرجاع الاستجابة: إذا كانت الدالة غير متزامنة وقمت بتعيين اسم الربط إلى
$returnفيfunction.json، يمكنك إرجاع الاستجابة مباشرة بدلا من تعيينها علىcontext.{ "type": "http", "direction": "out", "name": "$return" }module.exports = async function (context, request) { return { body: `Hello, world!` };
اضبط ربط الإخراج المسمى: يعمل هذا الخيار بنفس طريقة أي ربط غير HTTP. يجب أن يتطابق اسم الربط في
function.jsonمع المفتاح الموجود علىcontext.bindingsأو "response1" في المثال التالي:{ "type": "http", "direction": "out", "name": "response1" }module.exports = async function (context, request) { context.bindings.response1 = { body: `Hello, world!` };
استدعاء
context.res.send(): تم إهمال هذا الخيار. هي تستدعيcontext.done()ضمنيا ولا يمكنك استخدامها في دالة غير متزامنة.module.exports = function (context, request) { context.res.send(`Hello, world!`);
إذا قمت بإنشاء كائن جديد عند تعيين الاستجابة، يجب أن يتطابق هذا الكائن مع الواجهة HttpResponseSimple ، التي تحتوي على الخصائص التالية:
| Property | Type | Description |
|---|---|---|
headers |
Record<string, string> (اختياري) |
عناوين استجابة HTTP. |
cookies |
Cookie[] (اختياري) |
ملفات تعريف ارتباط استجابة HTTP. |
body |
any (اختياري) |
نص استجابة HTTP. |
statusCode |
number (اختياري) |
رمز حالة استجابة HTTP. إذا لم يتم تعيين، يتم تعيين افتراضيا إلى 200. |
status |
number (اختياري) |
نفس statusCode. يتم تجاهل هذه الخاصية إذا statusCode تم تعيينها. |
يمكنك أيضا تعديل context.res الكائن دون الكتابة فوقه. يستخدم الكائن الافتراضي context.res الواجهة HttpResponseFull التي تدعم الأساليب التالية بالإضافة إلى الخصائص HttpResponseSimple :
| Method | Description |
|---|---|
status() |
تعيين الحالة. |
setHeader() |
تعيين حقل رأس.
ملاحظة:res.set() وأيضا res.header() يتم دعمهم ويفعلون نفس الشيء. |
getHeader() |
يحصل على حقل رأس (header).
ملاحظة:res.get() كما أنه مدعوم ويفعل نفس الشيء. |
removeHeader() |
إزالة رأس. |
type() |
تعيين رأس "نوع المحتوى". |
send() |
تم إهمال هذا الأسلوب. يقوم بتعيين النص الأساسي والمكالمات context.done() للإشارة إلى انتهاء وظيفة المزامنة.
ملاحظة:res.end() كما أنه مدعوم ويفعل نفس الشيء. |
sendStatus() |
تم إهمال هذا الأسلوب. يقوم بتعيين رمز الحالة والمكالمات context.done() للإشارة إلى انتهاء وظيفة المزامنة. |
json() |
تم إهمال هذا الأسلوب. يقوم بتعيين "نوع المحتوى" إلى "application/json"، وتعيين النص الأساسي، واستدعاءات context.done() للإشارة إلى انتهاء وظيفة المزامنة. |
يمكنك ضبط الاستجابة بعدة طرق. على سبيل المثال، يمكنك استخدام:
واجهة بسيطة مع النص
HttpResponseInit: هذا الخيار هو الطريقة الأكثر اختصارا لإعادة الردود.return { body: `Hello, world!` };
تحتوي الواجهة HttpResponseInit على الخصائص التالية:
| Property | Type | Description |
|---|---|---|
body |
BodyInit (اختياري) |
نص استجابة ArrayBufferHTTP كأحد أو AsyncIterable<Uint8Array>أو Blobأو FormDataأو Iterable<Uint8Array>أو . NodeJS.ArrayBufferViewURLSearchParamsnullstring |
jsonBody |
any (اختياري) |
نص استجابة HTTP قابل للتسلسل JSON. إذا تم تعيينها، يتم تجاهل الخاصية HttpResponseInit.body لصالح هذه الخاصية. |
status |
number (اختياري) |
رمز حالة استجابة HTTP. إذا لم يتم تعيين، يتم تعيين افتراضيا إلى 200. |
headers |
HeadersInit (اختياري) |
عناوين استجابة HTTP. |
cookies |
Cookie[] (اختياري) |
ملفات تعريف ارتباط استجابة HTTP. |
كفئة ذات نوع
HttpResponse: يوفر هذا الخيار أساليب مساعدة لقراءة وتعديل أجزاء مختلفة من الاستجابة مثل الرؤوس.const response = new HttpResponse({ body: `Hello, world!` }); response.headers.set("content-type", "application/json"); return response;
HttpResponse تقبل الفئة اختياريا HttpResponseInit كوسيطة لمنشئها ولها الخصائص التالية:
| Property | Type | Description |
|---|---|---|
status |
number |
رمز حالة استجابة HTTP. |
headers |
Headers |
عناوين استجابة HTTP. |
cookies |
Cookie[] |
ملفات تعريف ارتباط استجابة HTTP. |
body |
ReadableStream | null |
النص الأساسي كتدفق قابل للقراءة. |
bodyUsed |
boolean |
قيمة منطقية تشير إلى ما إذا كان النص قد تمت قراءته بالفعل. |
تدفقات HTTP
تدفقات HTTP هي ميزة تسهل معالجة البيانات الكبيرة، ودفق استجابات OpenAI، وتقديم محتوى ديناميكي، ودعم سيناريوهات HTTP الأساسية الأخرى. يتيح لك دفق الطلبات والاستجابات من نقاط نهاية HTTP في تطبيق الوظائف Node.js. استخدم تدفقات HTTP في السيناريوهات التي يتطلب فيها تطبيقك التبادل والتفاعل في الوقت الحقيقي بين العميل والخادم عبر HTTP. يمكنك أيضا استخدام تدفقات HTTP للحصول على أفضل أداء وموثوقية لتطبيقاتك عند استخدام HTTP.
Important
تدفقات HTTP غير مدعومة في نموذج v3.
قم بالترقية إلى نموذج v4 لاستخدام ميزة تدفق HTTP.
تدعم الأنواع الموجودة HttpRequest و HttpResponse في نموذج البرمجة v4 بالفعل طرقا مختلفة للتعامل مع نص الرسالة، بما في ذلك كتدفق.
Prerequisites
-
@azure/functionsإصدار حزمة npm 4.3.0 أو أحدث. - دالات Azure runtime الإصدار 4.28 أو أحدث.
- دالات Azure Core Tools الإصدار 4.0.5530 أو أحدث، والذي يحتوي على النسخة الصحيحة من وقت التشغيل.
تمكين التدفقات
استخدم هذه الخطوات لتمكين تدفقات HTTP في تطبيق الوظائف الخاص بك في Azure وفي مشاريعك المحلية:
إذا كنت تخطط لبث كميات كبيرة من البيانات، قم بتعديل إعداد
FUNCTIONS_REQUEST_BODY_SIZE_LIMITفي Azure. الحد الافتراضي لحجم الجسم المسموح به هو104857600، مما يحد من حجم طلباتك إلى حوالي 100 ميجابايت.للتطوير المحلي ، أضف
FUNCTIONS_REQUEST_BODY_SIZE_LIMITأيضا إلى ملفlocal.settings.json.أضف التعليمات البرمجية التالية إلى تطبيقك في أي ملف مضمن في الحقل الرئيسي.
const { app } = require("@azure/functions"); app.setup({ enableHttpStream: true });
أمثلة على الدفق
المثال التالي يظهر دالة يتم تفعيلها عبر HTTP تستقبل البيانات من خلال طلب HTTP POST. تقوم الدالة بتدفق هذه البيانات إلى ملف إخراج محدد:
const { app } = require('@azure/functions');
const { createWriteStream } = require('fs');
const { Writable } = require('stream');
app.http('httpTriggerStreamRequest', {
methods: ['POST'],
authLevel: 'anonymous',
handler: async (request, context) => {
const writeStream = createWriteStream('<output file path>');
await request.body.pipeTo(Writable.toWeb(writeStream));
return { body: 'Done!' };
},
});
المثال التالي يظهر دالة يتم تفعيلها بواسطة HTTP تقوم ببث محتوى الملف كاستجابة لطلبات HTTP GET الواردة:
const { app } = require('@azure/functions');
const { createReadStream } = require('fs');
app.http('httpTriggerStreamResponse', {
methods: ['GET'],
authLevel: 'anonymous',
handler: async (request, context) => {
const body = createReadStream('<input file path>');
return { body };
},
});
للحصول على تطبيق عينات جاهز للتشغيل يستخدم التدفقات، اطلع على هذا المثال على GitHub.
اعتبارات البث
- استخدمها
request.bodyللحصول على أكبر فائدة من استخدام الجداول. لا يزال بإمكانك استخدام طرق مثلrequest.text()، التي تعيد الجسم دائما كخيط.
Hooks
طراز v3 لا يدعم الخطاف. قم بالترقية إلى نموذج v4 لاستخدام الخطافات.
استخدم هوك لتنفيذ الكود في نقاط مختلفة من دورة حياة دالات Azure. ترتيب تسجيل الخطاطيف يحدد ترتيب تنفيذها. يمكنك تسجيل الخطافات من أي ملف في تطبيقك. يوجد نطاقان للخطافات: مستوى "التطبيق" ومستوى "الاستدعاء".
خطافات الاستدعاء
خطاطيف الاستدعاء تعمل مرة واحدة لكل استدعاء لوظيفتك. يعمل الخطاف preInvocation قبل تشغيل الدالة، والخطاف postInvocation بعد تشغيل الدالة. افتراضيا، ينفذ الخطاف لجميع أنواع المحفزات، لكن يمكنك أيضا تصفية حسب النوع. يوضح المثال التالي كيفية تسجيل خطاف استدعاء وتصفية حسب نوع المشغل:
const { app } = require('@azure/functions');
// Pre-invocation hook with trigger filtering
app.hook.preInvocation('httpPreInvocation', async (context) => {
context.hookData.startTime = Date.now();
context.invocationContext.log(`Pre-invocation hook executed for ${context.invocationContext.functionName}`);
// Add custom headers or modify function handler if needed
if (context.functionHandler.name === 'httpTrigger') {
context.invocationContext.log('HTTP function detected, preparing request processing');
}
}, {
filter: ['httpTrigger']
});
// Post-invocation hook
app.hook.postInvocation('httpPostInvocation', async (context) => {
const duration = Date.now() - context.hookData.startTime;
context.invocationContext.log(`Function ${context.invocationContext.functionName} completed in ${duration}ms`);
// Log results or errors
if (context.error) {
context.invocationContext.log.error(`Function failed: ${context.error.message}`);
} else {
context.invocationContext.log(`Function succeeded with result: ${JSON.stringify(context.result)}`);
}
}, {
filter: ['httpTrigger']
});
الوسيطة الأولى لمعالج الخطاف هي كائن سياق خاص بنوع الخطاف هذا.
يحتوي PreInvocationContext الكائن على الخصائص التالية:
| Property | Description |
|---|---|
inputs |
الحجج التي تقدمها للاستدعاء. |
functionHandler |
معالج الدالة للادعاء. تؤثر التغييرات التي تطرأ على هذه القيمة على الدالة نفسها. |
invocationContext |
تم تمرير كائن سياق الاستدعاء إلى الدالة. |
hookData |
المكان الموصى به لتخزين البيانات ومشاركتها بين الخطافات في نفس النطاق. استخدم اسم خاصية فريد حتى لا يتعارض مع بيانات الخطاف الأخرى. |
يحتوي PostInvocationContext الكائن على الخصائص التالية:
| Property | Description |
|---|---|
inputs |
الحجج التي تقدمها للاستدعاء. |
result |
نتيجة الدالة. تؤثر التغييرات على هذه القيمة على النتيجة الإجمالية للدالة. |
error |
الخطأ الذي تم طرحه بواسطة الدالة، أو خال/غير معرف إذا لم يكن هناك خطأ. تؤثر التغييرات على هذه القيمة على النتيجة الإجمالية للدالة. |
invocationContext |
تم تمرير كائن سياق الاستدعاء إلى الدالة. |
hookData |
المكان الموصى به لتخزين البيانات ومشاركتها بين الخطافات في نفس النطاق. استخدم اسم خاصية فريد حتى لا يتعارض مع بيانات الخطاف الأخرى. |
خطافات التطبيق
يقوم وقت التشغيل بتنفيذ خطافات التطبيق مرة واحدة لكل نسخة من تطبيقك. يشغل appStart الخطاف أثناء التشغيل والخطاف appTerminate عند الإنهاء. خطافات إنهاء التطبيق لها وقت محدود للتنفيذ ولا يتم تنفيذها في جميع السيناريوهات.
مدة التشغيل دالات Azure حاليا لا تدعم تسجيل السياق خارج الاستدعاء. استخدم حزمة Application Insights npm لتسجيل البيانات أثناء الخطافات على مستوى التطبيق.
يسجل المثال التالي خطافات التطبيق:
const { app } = require('@azure/functions');
const appInsights = require('applicationinsights');
// Initialize Application Insights for app-level logging
appInsights.setup().start();
const client = appInsights.defaultClient;
// App start hook
app.hook.appStart('appStartup', async (context) => {
context.hookData.appStartTime = Date.now();
context.hookData.initializationData = {};
// Initialize shared resources, database connections, etc.
client.trackEvent({
name: 'FunctionAppStarted',
properties: {
timestamp: new Date().toISOString(),
nodeVersion: process.version
}
});
// Set up global configurations
process.env.APP_INITIALIZED = 'true';
});
// App terminate hook
app.hook.appTerminate('appShutdown', async (context) => {
const uptime = Date.now() - context.hookData.appStartTime;
// Cleanup resources, close connections, etc.
client.trackEvent({
name: 'FunctionAppTerminated',
properties: {
uptime: uptime,
timestamp: new Date().toISOString()
}
});
// Flush Application Insights data
await new Promise((resolve) => client.flush({ callback: resolve }));
});
الوسيطة الأولى لمعالج الخطاف هي كائن سياق خاص بنوع الخطاف هذا.
AppStartContext للكائن الخاصية التالية:
| Property | Description |
|---|---|
hookData |
المكان الموصى به لتخزين البيانات ومشاركتها بين الخطافات في نفس النطاق. استخدم اسم خاصية فريد حتى لا يتعارض مع بيانات الخطاف الأخرى. |
AppTerminateContext للكائن الخاصية التالية:
| Property | Description |
|---|---|
hookData |
المكان الموصى به لتخزين البيانات ومشاركتها بين الخطافات في نفس النطاق. استخدم اسم خاصية فريد حتى لا يتعارض مع بيانات الخطاف الأخرى. |
أفضل الممارسات في الخطاف
عند استخدام الخطافات في دالات Azure الخاص بك، ضع في اعتبارك أفضل الممارسات:
الاعتبارات الخاصة بالأداء
- حافظ على وقت تنفيذ الخطاف في الحد الأدنى لتجنب التأثير على أداء الوظيفة.
- استخدم العمليات غير المتزامنة حيثما أمكن لمنع الحظر.
- ضع في اعتبارك عبء الخطاف عند معالجة الطلبات ذات الحجم الكبير.
معالجة الأخطاء
- دائما قم بتضمين التعامل الصحيح مع الأخطاء في خطافاتك.
- لا تدع أعطال الخطاف تسبب أعطالا في الوظائف إلا إذا كان ذلك ضروريا للغاية.
- أخطاء خطاف السجل بشكل مناسب للتصحيح.
مشاركة البيانات
- يستخدم
hookDataلمشاركة المعلومات بين خطافات ما قبل وبعد الاستدعاء. - استخدم أسماء عقارات فريدة لتجنب التعارض مع الروابط الأخرى.
- تنظيف بيانات الوصلات عندما لا تكون هناك حاجة لمنع تسرب الذاكرة.
التصفية
- استخدم تصفية نوع الزناد لضمان أن الخطاطيف تعمل فقط للوظائف ذات الصلة.
- كن محددا في اختيار الفلاتر لتحسين الأداء.
التحجيم والتزامن
بشكل افتراضي، دالات Azure تراقب تلقائيا الحمل على تطبيقك وتنشئ المزيد من مثيلات المضيف Node.js حسب الحاجة. يستخدم دالات Azure عتبات مدمجة (غير قابلة لتكوين المستخدم) لأنواع الزناد المختلفة لتحديد متى تضيف مثيلات، مثل عمر الرسائل وحجم قائمة الانتظار ل QueueTrigger. لمزيد من المعلومات، راجع كيف تعمل Consumption and Premium plans.
سلوك التحجيم هذا كافٍ للعديد من تطبيقات Node.js. بالنسبة إلى التطبيقات المرتبطة بـ CPU، يمكنك تحسين الأداء بشكل أكبر باستخدام عمليات عاملة متعددة اللغة. يمكنك زيادة عدد عمليات العامل لكل مضيف من الافتراضي 1 إلى 10 كحد أقصى باستخدام إعداد تطبيق FUNCTIONS_WORKER_PROCESS_COUNT . يحاول دالات Azure بعد ذلك توزيع استدعاءات الوظائف المتزامنة بالتساوي بين هؤلاء الموظفين. يقلل هذا السلوك من احتمالية أن تمنع الدالة كثيفة الاستخدام لوحدة المعالجة المركزية الوظائف الأخرى من التشغيل. ينطبق هذا الإعداد على كل مضيف ينشئه دالات Azure عند توسيع تطبيقك لتلبية الطلب.
Warning
FUNCTIONS_WORKER_PROCESS_COUNT استخدم الإعداد بحذر. يمكن أن تؤدي العمليات المتعددة التي تعمل في نفس المثيل إلى سلوك غير متوقع وزيادة أوقات تحميل الدالة. إذا استخدمت هذا الإعداد، فإن التشغيل من ملف حزمة يمكن أن يعوض هذه السلبيات.
إصدار العقدة
يمكنك مشاهدة الإصدار الحالي الذي يستخدمه وقت التشغيل عن طريق تسجيل process.version من أي وظيفة. راجع supported versions للحصول على قائمة بالإصدارات Node.js التي يدعمها كل نموذج برمجة.
إعداد إصدار Node
تعتمد الطريقة التي تقوم بها بترقية إصدار Node.js على نظام التشغيل الذي يتم تشغيل تطبيق الوظائف عليه.
عندما يعمل على Windows، قم بتعيين النسخة Node.js باستخدام WEBSITE_NODE_DEFAULT_VERSION إعداد التطبيق. قم بتحديث هذا الإعداد إما باستخدام Azure CLI أو في بوابة Azure.
لمزيد من المعلومات حول Node.js الإصدارات، راجع الإصدارات المدعومة.
قبل ترقية النسخة Node.js الخاصة بك، تأكد من أن تطبيق الوظائف يعمل على أحدث إصدار من وقت تشغيل دالات Azure. إذا كنت بحاجة إلى ترقية إصدار وقت التشغيل الخاص بك، راجع ترحيل التطبيقات من الإصدار 3.x دالات Azure إلى الإصدار 4.x.
- واجهة سطر الأوامر Azure (Azure CLI)
- مدخل Azure
شغل أمر Azure CLI az functionapp config appsettings set لتحديث النسخة Node.js لتطبيق الوظائف الخاص بك الذي يعمل على Windows:
az functionapp config appsettings set --settings WEBSITE_NODE_DEFAULT_VERSION=~22 \
--name <FUNCTION_APP_NAME> --resource-group <RESOURCE_GROUP_NAME>
هذا الأمر يضبط WEBSITE_NODE_DEFAULT_VERSION إعداد التطبيق على إصدار ~22LTS المدعوم .
بعد إجراء التغييرات، يعاد تطبيق الوظائف الخاص بك التشغيل. لمعرفة المزيد حول دعم الوظائف Node.js، راجع نهج دعم وقت تشغيل اللغة.
متغيرات البيئة
استخدم متغيرات البيئة لإدارة أسرار التشغيل مثل سلاسل الاتصال، والمفاتيح، ونقاط النهاية. استخدمها أيضا في الإعدادات البيئية، مثل تحديد المتغيرات التحليلية. أضف متغيرات البيئة في كل من البيئات المحلية والسحابية، والوصول إليها من خلال process.env كود الدالة الخاص بك.
يسجل WEBSITE_SITE_NAME المثال التالي متغير البيئة:
module.exports = async function (context) {
context.log(`WEBSITE_SITE_NAME: ${process.env["WEBSITE_SITE_NAME"]}`);
};
async function timerTrigger1(myTimer, context) {
context.log(`WEBSITE_SITE_NAME: ${process.env["WEBSITE_SITE_NAME"]}`);
}
في بيئة التنمية المحلية
عند التشغيل محليا، يتضمن مشروع الوظائف ملفاlocal.settings.json، حيث تقوم بتخزين متغيرات البيئة في Values العنصر .
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "node",
"CUSTOM_ENV_VAR_1": "hello",
"CUSTOM_ENV_VAR_2": "world"
}
}
In Azure cloud environment
عند تشغيل Azure، يتيح لك تطبيق الوظائف تعيين واستخدام إعدادات التطبيق، مثل سلاسل اتصال الخدمة، ويعرض هذه الإعدادات كمتغيرات بيئية أثناء التنفيذ.
توجد عدة طرق يمكنك من خلالها إضافة إعدادات تطبيق الوظائف وتحديثها وحذفها:
تتطلب التغييرات في إعدادات تطبيق الوظائف إعادة تشغيل تطبيق الوظائف.
متغيرات بيئة العامل
Node.js يحتوي على عدة متغيرات بيئة دوال خاصة به:
languageWorkers__node__arguments
استخدم هذا الإعداد لتحديد الوسائط المخصصة عند بدء Node.js العملية. غالبا ما تستخدمه محليا لبدء العامل في وضع التصحيح، لكن يمكنك أيضا استخدامه في Azure إذا كنت بحاجة إلى وسائط مخصصة.
Warning
إذا أمكن، تجنب استخدامه languageWorkers__node__arguments في Azure لأنه قد يؤثر سلبا على أوقات بدء التشغيل في البرودة. بدلا من استخدام العمالة المدفئة مسبقا، يجب أن يبدأ وقت التشغيل عامل جديد من الصفر باستخدام الوسائط المخصصة الخاصة بك.
logginglogLevelWorker
استخدم هذا الإعداد لضبط مستوى السجل الافتراضي لسجلات العمال الخاصة Node.js. بشكل افتراضي، يتم عرض سجلات التحذير أو الخطأ فقط، ولكن يمكنك تعيينها إلى information أو debug للمساعدة في تشخيص المشكلات مع العامل Node.js. لمزيد من المعلومات، راجع تكوين مستويات السجل.
وحدات ECMAScript (المعاينة)
Note
وحدات ECMAScript حاليا ميزة معاينة في Node.js 14 أو أعلى في دالات Azure.
وحدات ECMAScript (وحدات ES) هي نظام الوحدة القياسية الرسمي الجديد ل Node.js. حتى الآن، تستخدم نماذج التعليمات البرمجية في هذه المقالة بناء الجملة CommonJS. عند تشغيل دالات Azure في Node.js 14 أو أعلى، يمكنك اختيار كتابة الدوال باستخدام بناء جملة وحدات ES.
لاستخدام الوحدات ES في وظيفة، غير اسم الملف الخاص بها لاستخدام ملحق .mjs. مثال ملف index.mjs التالي هو دالة يتم تشغيلها بواسطة HTTP تستخدم بناء جملة الوحدات النمطية ES لاستيراد uuid المكتبة وإرجاع قيمة.
import { v4 as uuidv4 } from "uuid";
async function httpTrigger1(context, request) {
context.res.body = uuidv4();
}
export default httpTrigger;
import { v4 as uuidv4 } from "uuid";
async function httpTrigger1(request, context) {
return { body: uuidv4() };
}
app.http("httpTrigger1", {
methods: ["GET", "POST"],
handler: httpTrigger1,
});
تكوين نقطة إدخال الوظيفة
استخدم الخصائص function.jsonscriptFile وتعيين entryPoint موقع واسم الدالة المصدرة. عندما تستخدم TypeScript، تحتاج إلى الخاصية scriptFile ويجب أن تشير إلى JavaScript المترجم.
استخدام scriptFile
افتراضيا، تعمل دالة جافاسكريبت من index.js. يشارك هذا الملف نفس الدليل الأم مع الملف المقابل function.json .
استخدمه scriptFile لتنظيم هيكل المجلدات. المثال التالي يوضح طريقة واحدة لإعداد مجلداتك:
<project_root>/
| - node_modules/
| - myFirstFunction/
| | - function.json
| - lib/
| | - sayHello.js
| - host.json
| - package.json
يجب أن function.json يتضمن الملف خاصية myFirstFunctionscriptFile تشير إلى الملف الذي يتم فيه الانتقال إلى الدالة المصدرة للتشغيل.
{
"scriptFile": "../lib/sayHello.js",
"bindings": [
...
]
}
استخدام entryPoint
في نموذج v3، يجب تصدير دالة باستخدام module.exports بحيث يمكن العثور على الدالة وتشغيلها. افتراضيا، الوظيفة التي تعمل عند تفعيلها هي التصدير الوحيد من ذلك الملف. يمكن أن يكون أيضا التصدير المسمى run أو التصدير المسمى index. يعين entryPoint المثال التالي إلى function.json قيمة مخصصة، "logHello":
{
"entryPoint": "logHello",
"bindings": [
...
]
}
async function logHello(context) {
context.log("Hello, world!");
}
module.exports = { logHello };
Recommendations
يصف هذا القسم عدة أنماط مؤثرة لتطبيقات Node.js يجب عليك اتباعها.
اختر خطط خدمة التطبيقات single-vCPU
عند إنشاء تطبيق وظيفي يستخدم خطة خدمة التطبيقات، اختر خطة وحدة معالجة مركزية واحدة بدلا من خطة تحتوي على عدة معالجات افتراضية. اليوم، تعمل الوظائف Node.js الوظائف بكفاءة أكبر على الأجهزة الافتراضية ذات المعالج الواحد فقط، واستخدام الأجهزة الافتراضية الأكبر لا يجلب التحسينات المتوقعة في الأداء. عند الحاجة، يمكنك توسيع التقنية بإضافة المزيد من نسخ الوحدات الافتراضية ذات المعالج الواحد، أو تفعيل التكبير التلقائي. لمزيد من المعلومات، راجع حساب مثيل المقياس يدويًا أو تلقائيًا.
تشغيل من ملف حزمة
عندما تطور دالات Azure في نموذج الاستضافة بدون خوادم، تصبح الهجمات الباردة واقعا. تشير البداية الباردة إلى المرة الأولى التي يبدأ فيها تطبيق الوظائف الخاص بك بعد فترة من عدم النشاط ، ويستغرق وقتا أطول لبدء التشغيل. بالنسبة Node.js التطبيقات ذات أشجار التبعية الكبيرة على وجه الخصوص، يمكن أن يكون البدء البارد مهما. لتسريع عملية التشغيل البارد، شغل وظائفك كملف حزمة عند الإمكان. تستخدم العديد من طرق النشر هذا النموذج بشكل افتراضي، ولكن إذا كنت تواجه بدايات باردة كبيرة، تحقق من أنك تعمل بهذه الطريقة.
استخدام async وawait
عند كتابة دالات Azure في Node.js، اكتب الكود باستخدام الكلمات async المفتاحية وawait. كتابة الكود باستخدام async و await بدلا من الاستدعاءات أو .then.catch مع Promises تساعدك على تجنب مشكلتين شائعتين:
- طرح الاستثناءات المعلقة التي تعطل عملية Node.js، يحتمل أن يؤثر على تنفيذ وظائف أخرى.
- سلوك غير متوقع، مثل السجلات المفقودة من
context.log، بسبب استدعاءات غير متزامنة لم يتم انتظارها بشكل صحيح.
في المثال التالي، يتم استدعاء الأسلوب fs.readFile غير المتزامن مع دالة رد اتصال الخطأ الأول كمعلمة ثانية. تتسبب هذه التعليمة البرمجية في كلتا المشكلتين المذكورتين سابقا. يمكن أن يؤدي الاستثناء الذي لم يتم اكتشافه بشكل صريح في النطاق الصحيح إلى تعطل العملية بأكملها (المشكلة رقم 1). العودة دون التأكد من انتهاء الاستدعاء يعني أن استجابة HTTP أحيانا تكون فارغة (المشكلة #2).
// DO NOT USE THIS CODE
const { app } = require('@azure/functions');
const fs = require('fs');
app.http('httpTriggerBadAsync', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: async (request, context) => {
let fileData;
fs.readFile('./helloWorld.txt', (err, data) => {
if (err) {
context.error(err);
// BUG #1: This will result in an uncaught exception that crashes the entire process
throw err;
}
fileData = data;
});
// BUG #2: fileData is not guaranteed to be set before the invocation ends
return { body: fileData };
},
});
في المثال التالي، يتم استدعاء الأسلوب fs.readFile غير المتزامن مع دالة رد اتصال الخطأ الأول كمعلمة ثانية. هذا الكود يسبب كلا المشكلتين المذكورتين سابقا. الاستثناء الذي لم يتم تحديده صراحة في النطاق الصحيح يمكن أن يتسبب في تعطل العملية بأكملها (المشكلة #1). استدعاء الطريقة القديمة context.done() خارج نطاق الاستدعاء يمكن أن يشير إلى انتهاء الدالة قبل قراءة الملف (المشكلة #2). في هذا المثال، الاتصال بـcontext.done() مبكرة جدًا يؤدي إلى إدخالات سجل مفقودة بدءًا من Data from file:.
// NOT RECOMMENDED PATTERN
const fs = require("fs");
module.exports = function (context) {
fs.readFile("./hello.txt", (err, data) => {
if (err) {
context.log.error("ERROR", err);
// BUG #1: This will result in an uncaught exception that crashes the entire process
throw err;
}
context.log(`Data from file: ${data}`);
// context.done() should be called here
});
// BUG #2: Data is not guaranteed to be read before the Azure Function's invocation ends
context.done();
};
استخدم الكلمات async المفتاحية وأنت await لتجنب هاتين المشكلتين. معظم واجهات برمجة التطبيقات في نظام Node.js الآن تدعم الوعود بشكل ما. على سبيل المثال، بدءا من الإصدار 14، توفر fs/promises Node.js واجهة برمجة تطبيقات لتحل محل fs واجهة برمجة تطبيقات الاستدعاء.
في المثال التالي، تفشل أي استثناءات غير معالجة تم طرحها أثناء تنفيذ الدالة فقط في استدعاء الفردية التي أثارت الاستثناء.
await تعني الكلمة الأساسية أن الخطوات التالية readFile تنفذ فقط بعد اكتمالها.
// Recommended pattern
const { app } = require('@azure/functions');
const fs = require('fs/promises');
app.http('httpTriggerGoodAsync', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: async (request, context) => {
try {
const fileData = await fs.readFile('./helloWorld.txt');
return { body: fileData };
} catch (err) {
context.error(err);
// This rethrown exception will only fail the individual invocation, instead of crashing the whole process
throw err;
}
},
});
عندما تستخدم async و await، لا تحتاج إلى الاتصال بإعادة context.done() الاتصال.
// Recommended pattern
const fs = require("fs/promises");
module.exports = async function (context) {
let data;
try {
data = await fs.readFile("./hello.txt");
} catch (err) {
context.log.error("ERROR", err);
// This rethrown exception will be handled by the Functions Runtime and will only fail the individual invocation
throw err;
}
context.log(`Data from file: ${data}`);
};
Troubleshoot
راجع دليل استكشاف الأخطاء وإصلاحها Node.js.
الخطوات التالية
لمزيد من المعلومات، راجع الموارد التالية: