الترحيل إلى الإصدار 4 من نموذج البرمجة Node.js ل Azure Functions

تتناول هذه المقالة الاختلافات بين الإصدار 3 والإصدار 4 من نموذج البرمجة Node.js وكيفية ترقية تطبيق v3 موجود. إذا كنت ترغب في إنشاء تطبيق v4 جديد بدلا من ترقية تطبيق v3 موجود، فشاهد البرنامج التعليمي إما ل Visual Studio Code (VS Code) أو Azure Functions Core Tools. تستخدم هذه المقالة تنبيهات "تلميح" لتسليط الضوء على أهم الإجراءات الملموسة التي يجب اتخاذها لترقية تطبيقك.

تم تصميم الإصدار 4 لتزويد مطوري Node.js بالمزايا التالية:

  • توفير تجربة مألوفة وبديهية لمطوري Node.js.
  • اجعل بنية الملف مرنة مع دعم التخصيص الكامل.
  • قم بالتبديل إلى نهج يركز على التعليمات البرمجية لتعريف تكوين الدالة.

الاعتبارات

  • لا ينبغي الخلط بين نموذج البرمجة Node.js ووقت تشغيل Azure Functions:
    • نموذج البرمجة: يحدد كيفية تأليف التعليمات البرمجية الخاصة بك وهو خاص ب JavaScript وTypeScript.
    • وقت التشغيل: يحدد السلوك الأساسي ل Azure Functions ويتم مشاركته عبر جميع اللغات.
  • يرتبط إصدار نموذج البرمجة ارتباطا صارما بإصدار حزمة @azure/functions npm. يتم إصداره بشكل مستقل عن وقت التشغيل. يستخدم كل من وقت التشغيل ونموذج البرمجة الرقم 4 كإصدار رئيسي أحدث، ولكن هذه صدفة.
  • لا يمكنك خلط نماذج البرمجة v3 وv4 في نفس تطبيق الوظائف. بمجرد تسجيل وظيفة v4 واحدة في تطبيقك، يتم تجاهل أي وظائف v3 مسجلة في ملفات function.json .

المتطلبات

يتطلب الإصدار 4 من نموذج البرمجة Node.js الحد الأدنى من الإصدارات التالية:

تضمين حزمة npm

في v4، تحتوي حزمة @azure/functions npm على التعليمات البرمجية المصدر الأساسية التي تدعم نموذج البرمجة Node.js. في الإصدارات السابقة، كان هذا الرمز الذي تم شحنه مباشرة في Azure وحزمة npm يحتوي فقط على أنواع TypeScript. تحتاج الآن إلى تضمين هذه الحزمة لكل من تطبيقات TypeScript وJavaScript. يمكنك تضمين الحزمة لتطبيقات v3 الموجودة، ولكنها غير مطلوبة.

تلميح

تأكد من إدراج الحزمة @azure/functions في dependencies القسم (وليس devDependencies) من ملف package.json الخاص بك. يمكنك تثبيت v4 باستخدام الأمر التالي:

npm install @azure/functions

تعيين نقطة إدخال التطبيق

في الإصدار 4 من نموذج البرمجة، يمكنك هيكلة التعليمات البرمجية الخاصة بك كيفما تريد. الملفات الوحيدة التي تحتاجها في جذر تطبيقك هي host.json و package.json.

وإلا، يمكنك تعريف بنية الملف عن طريق تعيين main الحقل في ملف package.json الخاص بك. يمكنك تعيين main الحقل إلى ملف واحد أو ملفات متعددة باستخدام نمط glob. يعرض الجدول التالي أمثلة main على قيم الحقل:

مثال ‏‏الوصف
src/index.js تسجيل الوظائف من ملف جذر واحد.
src/functions/*.js تسجيل كل دالة من ملفها الخاص.
src/{index.js,functions/*.js} تركيبة حيث تقوم بتسجيل كل وظيفة من ملفها الخاص، ولكن لا يزال لديك ملف جذر للتعليمات البرمجية العامة على مستوى التطبيق.
مثال ‏‏الوصف
dist/src/index.js تسجيل الوظائف من ملف جذر واحد.
dist/src/functions/*.js تسجيل كل دالة من ملفها الخاص.
dist/src/{index.js,functions/*.js} تركيبة حيث تقوم بتسجيل كل وظيفة من ملفها الخاص، ولكن لا يزال لديك ملف جذر للتعليمات البرمجية العامة على مستوى التطبيق.

تلميح

تأكد من تحديد main حقل في ملف package.json.

تبديل ترتيب الوسيطات

يعد إدخال المشغل، بدلا من سياق استدعاء، الآن الوسيطة الأولى لمعالج الدالة. سياق استدعاء، الآن الوسيطة الثانية، مبسط في v4 وليس مطلوبا مثل إدخال المشغل. يمكنك تركه متوقفا عن التشغيل إذا كنت لا تستخدمه.

تلميح

قم بتبديل ترتيب الوسيطات الخاصة بك. على سبيل المثال، إذا كنت تستخدم مشغل HTTP، فالتبديل (context, request) إلى أو (request, context) فقط (request) إذا كنت لا تستخدم السياق.

تعريف الدالة في التعليمات البرمجية

لم يعد عليك إنشاء ملفات تكوين function.json المنفصلة هذه وصيانتها. يمكنك الآن تعريف وظائفك بشكل كامل مباشرة في ملفات TypeScript أو JavaScript. بالإضافة إلى ذلك، تحتوي العديد من الخصائص الآن على إعدادات افتراضية بحيث لا تضطر إلى تحديدها في كل مرة.

const { app } = require('@azure/functions');

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || (await request.text()) || 'world';

        return { body: `Hello, ${name}!` };
    },
});
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || (await request.text()) || 'world';

    return { body: `Hello, ${name}!` };
}

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: httpTrigger1,
});

تلميح

انقل التكوين من ملف function.json إلى التعليمات البرمجية الخاصة بك. يتوافق نوع المشغل مع أسلوب على app الكائن في النموذج الجديد. على سبيل المثال، إذا كنت تستخدم httpTrigger نوعا في function.json، فاتصل app.http() بالتعليمات البرمجية لتسجيل الدالة. إذا كنت تستخدم timerTrigger، فاتصل ب app.timer().

مراجعة استخدامك للسياق

في الإصدار 4، context يتم تبسيط العنصر لتقليل التكرار وتسهيل اختبارات وحدة الكتابة. على سبيل المثال، قمنا بتبسيط الإدخال والإخراج الأساسيين بحيث يتم الوصول إليها فقط كوسيطة وقيمة إرجاع لمعالج الدالة.

لا يمكنك الوصول إلى الإدخال والإخراج الأساسيين context على الكائن بعد الآن، ولكن لا يزال يتعين عليك الوصول إلى المدخلات والمخرجات الثانوية على context الكائن. لمزيد من المعلومات حول المدخلات والمخرجات الثانوية، راجع دليل مطور Node.js.

الحصول على الإدخال الأساسي كوسيطة

يسمى الإدخال الأساسي أيضا المشغل وهو الإدخال أو الإخراج المطلوب الوحيد. يجب أن يكون لديك مشغل واحد (وواحد فقط).

يدعم الإصدار 4 طريقة واحدة فقط للحصول على إدخال المشغل، كوسيطة أولى:

async function httpTrigger1(request, context) {
  const onlyOption = request;
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
  const onlyOption = request;

تلميح

تأكد من عدم استخدام context.req أو context.bindings للحصول على الإدخال.

تعيين الإخراج الأساسي كقيمة إرجاع

يدعم الإصدار 4 طريقة واحدة فقط لتعيين الإخراج الأساسي، من خلال القيمة المرجعة:

return { 
  body: `Hello, ${name}!` 
};
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    // ...
    return { 
      body: `Hello, ${name}!` 
    };
}

تلميح

تأكد دائما من إرجاع الإخراج في معالج الدالة الخاص بك، بدلا من تعيينه مع context العنصر .

تسجيل السياق

في الإصدار 4، تم نقل أساليب التسجيل إلى الكائن الجذر context كما هو موضح في المثال التالي. لمزيد من المعلومات حول التسجيل، راجع دليل مطور Node.js.

context.log('This is an info log');
context.error('This is an error');
context.warn('This is an error');

إنشاء سياق اختبار

لا يدعم الإصدار 3 إنشاء سياق استدعاء خارج وقت تشغيل Azure Functions، لذلك قد تكون اختبارات وحدة التأليف صعبة. يسمح لك الإصدار 4 بإنشاء مثيل لسياق استدعاء، على الرغم من أن المعلومات أثناء الاختبارات غير مفصلة ما لم تقم بإضافتها بنفسك.

const testInvocationContext = new InvocationContext({
  functionName: 'testFunctionName',
  invocationId: 'testInvocationId'
});

مراجعة استخدامك للأنوع HTTP

أصبح طلب HTTP وأنواع الاستجابة الآن مجموعة فرعية من معيار الإحضار. لم تعد فريدة من نوعها ل Azure Functions.

تستخدم الأنواع الحزمة undici في Node.js. تتبع هذه الحزمة معيار الإحضار ويتم دمجها حاليا في Node.js core.

طلب Http

  • نص الرسالة. يمكنك الوصول إلى النص الأساسي باستخدام أسلوب خاص بالنوع الذي تريد تلقيه:

    const body = await request.text();
    const body = await request.json();
    const body = await request.formData();
    const body = await request.arrayBuffer();
    const body = await request.blob();
    
  • العنوان:

    const header = request.headers.get('content-type');
    
  • معلمة الاستعلام:

    const name = request.query.get('name');
    

HttpResponse

  • الحالة:

    return { status: 200 };
    
  • النص:

    استخدم الخاصية body لإرجاع معظم الأنواع مثل أو string Buffer:

    return { body: "Hello, world!" };
    

    استخدم الخاصية jsonBody لأسهل طريقة لإرجاع استجابة JSON:

    return { jsonBody: { hello: "world" } };
    
  • رأس الصفحة. يمكنك تعيين العنوان بطريقتين، اعتمادا على ما إذا كنت تستخدم HttpResponse الفئة أو الواجهة HttpResponseInit :

    const response = new HttpResponse();
    response.headers.set('content-type', 'application/json');
    return response;
    
    return {
      headers: { 'content-type': 'application/json' }
    };
    

تلميح

قم بتحديث أي منطق باستخدام طلب HTTP أو أنواع الاستجابة لمطابقة الأساليب الجديدة.

تلميح

قم بتحديث أي منطق باستخدام طلب HTTP أو أنواع الاستجابة لمطابقة الأساليب الجديدة. يجب أن تحصل على أخطاء إنشاء TypeScript لمساعدتك في تحديد ما إذا كنت تستخدم أساليب قديمة.

استكشاف الأخطاء وإصلاحها‬

راجع دليل Node.js Troubleshoot.