Azure Functions Node.js referensi pengembang

Referensi ini membahas cara mengembangkan Azure Functions menggunakan JavaScript dan TypeScript dengan @azure/functions paket npm. Untuk gambaran umum konsep Azure Functions yang dibagikan di semua bahasa, lihat referensi pengembang Azure Functions.

Sumber daya Link
Buat fungsi JavaScript pertama Anda Visual StudioCodeCLI/
Buat fungsi TypeScript pertama Anda Visual StudioCodeCLI/
Skenario dan contoh JavaScript/TypeScript
Referensi API @azure/functions API

Catatan

Artikel ini menampilkan konten untuk versi model pemrograman tertentu berdasarkan pemilih di bagian atas halaman. Versi yang Anda pilih harus sesuai dengan versi paket npm Anda @azure/functions . Anda tidak bisa mencampur fungsi v3 dan v4 dalam aplikasi yang sama. Jika Anda tidak memiliki paket di file Anda package.json, defaultnya adalah v3.

Model pemrograman

Azure Functions untuk Node.js mendukung dua versi model pemrograman. Proyek baru sebaiknya menggunakan versi 4.

Feature v4 (direkomendasikan) v3
Status GA GA (pemeliharaan)
@azure/functions Paket 4.x 3.x
Pendaftaran fungsi Berfokus pada kode (app.http(), app.timer()) Berbasis file (function.json)
Struktur file Flexibel Diperbaiki (satu folder per fungsi)
Versi runtime untuk Functions 4.25+ 4.x
Versi-versi Node.js 24.x, 22.x 24.x, 22.x

Dalam model pemrograman Node.js v4, Anda mendaftarkan fungsi dengan mengimpor objek app dari @azure/functions dan memanggil metode khusus pemicu. Fungsi-fungsi tersebut didefinisikan langsung dalam kode Anda dengan struktur file yang fleksibel. Setiap fungsi memiliki satu trigger yang memulai eksekusinya dan juga dapat memiliki binding, yaitu koneksi deklaratif ke layanan lain untuk membaca data input atau menulis data output. Untuk informasi lebih lanjut, lihat Pemicu dan pengikatan.

Pada model v4, Anda:

  • Register fungsi menggunakan metode khusus trigger seperti app.http(), app.timer(), dan app.storageQueue().
  • Akses input trigger sebagai argumen pertama ke handler Anda (misalnya, HttpRequest).
  • Kembalikan output utama langsung dari fungsi handler.
  • Gunakan context.extraInputs.get() untuk membaca dari pengikatan input tambahan seperti Blob Storage.
  • Gunakan context.extraOutputs.set() untuk menulis ke binding output tambahan, seperti antrean.
  • Setiap fungsi memiliki tepat satu trigger, tetapi dapat memiliki beberapa input dan output tambahan.
  • Anda dapat menyimpan data dalam variabel global untuk digunakan kembali di berbagai pemanggilan, tetapi jangan mengandalkan status ini untuk tetap ada. Runtime dapat mendaur ulang pekerja Anda kapan saja.

Dalam model pemrograman Node.js v3, Anda mendefinisikan setiap fungsi menggunakan function.json file konfigurasi dan kode JavaScript atau TypeScript yang sesuai. Anda mengatur fungsi dalam folder terpisah dengan struktur file tertentu. Setiap fungsi memiliki satu trigger yang memulai eksekusinya dan juga dapat memiliki binding, yaitu koneksi deklaratif ke layanan lain untuk membaca data input atau menulis data output. Untuk informasi lebih lanjut, lihat Pemicu dan pengikatan.

Dalam model v3, Anda:

  • Definisikan trigger dan binding dalam sebuah function.json file. Gunakan direction: "in" untuk input dan direction: "out" output.
  • Akses input pemicu sebagai argumen kedua untuk handler Anda, atau baca dari context.bindings.
  • Atur keluaran dengan menetapkan nilai ke context.bindings (misalnya, context.bindings.outputQueue). Untuk HTTP, gunakan context.res.
  • Proyek TypeScript memerlukan properti scriptFile di dalam function.json yang menunjuk ke file JavaScript hasil kompilasi.
  • Setiap fungsi hanya memiliki satu pemicu, tetapi dapat memiliki beberapa pengikatan input dan output.
  • Anda dapat menyimpan data dalam variabel global untuk digunakan kembali di berbagai pemanggilan, tetapi jangan mengandalkan status ini untuk tetap ada. Runtime dapat mendaur ulang pekerja Anda kapan saja.

Examples

Berikut adalah fungsi sederhana yang merespons permintaan 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}!` };
    }
});

Contoh non-HTTP berikut menggunakan pemicu timer:

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());
  }
});

Contoh berikut menunjukkan pemicu HTTP dengan pengikatan output antrean:

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 } };
  }
});

Berikut adalah fungsi sederhana yang merespons permintaan 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}!`
    };
};

Contoh non-HTTP berikut menggunakan pemicu timer:

{
  "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());
};

Contoh berikut menunjukkan pemicu HTTP dengan pengikatan output antrean:

{
  "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 }
    };
};

Membangun aplikasi fungsi Anda

Bagian ini membahas komponen penting untuk membuat dan menyusun aplikasi fungsi Node Anda, termasuk @azure/functions pustaka, struktur proyek, dan manajemen paket.

Pustaka @azure/functions

@azure/functions Pustaka TypeScript/JavaScript menyediakan tipe inti dan fungsi yang Anda gunakan untuk berinteraksi dengan runtime Azure Functions. Untuk melihat semua jenis dan metode yang tersedia, kunjungi @azure/functions API.

Kode fungsi Anda dapat digunakan @azure/functions untuk:

  • Daftarkan fungsi dan definisikan trigger (model v4).
  • Akses data input trigger yang diketik kuat (misalnya, HttpRequest, Timer).
  • Buat nilai output yang diketik (seperti HttpResponseInit).
  • Berinteraksi dengan konteks yang disediakan saat eksekusi dan data pengikatan.

Jika Anda menggunakan @azure/functions di aplikasi Anda, sertakan dalam dependensi proyek Anda:

{
  "dependencies": {
    "@azure/functions": "^4.0.0"
  }
}

Catatan

Pustaka @azure/functions mendefinisikan antarmuka pemrograman untuk Node.js Azure Functions, tetapi bukan SDK yang serbaguna. Gunakan secara khusus untuk menulis dan menjalankan fungsi dalam runtime Azure Functions.

Konfigurasi TypeScript

Untuk pengalaman pengembangan TypeScript terbaik, pastikan tsconfig.json Anda menyertakan konfigurasi yang tepat:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "outDir": "dist",
    "rootDir": ".",
    "sourceMap": true,
    "strict": false,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

Struktur folder

Proyek JavaScript memerlukan struktur folder seperti yang ditunjukkan pada contoh berikut:

<project_root>/
 | - .vscode/
 | - node_modules/
 | - myFirstFunction/
 | | - index.js
 | | - function.json
 | - mySecondFunction/
 | | - index.js
 | | - function.json
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - package.json

Folder proyek utama, <project_root>, dapat berisi file berikut:

  • .vscode/: (Opsional) Berisi konfigurasi Visual Studio Code yang disimpan. Untuk mempelajari selengkapnya, lihat pengaturan Visual Studio Code.
  • myFirstFunction/function.json: Berisi konfigurasi untuk pemicu, input, dan output fungsi. Nama direktori menentukan nama fungsi Anda.
  • myFirstFunction/index.js: Menyimpan kode fungsi Anda. Untuk mengubah jalur file default ini, lihat menggunakan scriptFile.
  • .funcignore: (Opsional) Menyatakan file yang seharusnya tidak diterbitkan ke Azure. Biasanya, file ini berisi .vscode/ untuk mengabaikan pengaturan editor Anda, menguji/ mengabaikan kasus pengujian, dan local.settings.json mencegah pengaturan aplikasi lokal dipublikasikan.
  • host.json: Berisi opsi konfigurasi yang memengaruhi semua fungsi dalam instans aplikasi fungsi. File ini dipublikasikan ke Azure. Tidak semua opsi didukung saat berjalan secara lokal. Untuk mempelajari lebih lanjut, lihat host.json.
  • local.settings.json: Untuk menyimpan pengaturan aplikasi dan string koneksi yang digunakan saat berjalan secara lokal. File ini tidak diterbitkan ke Azure. Untuk mempelajari lebih lanjut, lihat local.settings.file.
  • package.json: Berisi opsi konfigurasi seperti daftar ketergantungan paket, titik masuk utama, dan skrip.

Proyek JavaScript mengikuti struktur folder yang direkomendasikan dalam contoh berikut:

<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

Folder proyek utama, <project_root>, dapat berisi file berikut:

  • .vscode/: (Opsional) Berisi konfigurasi Visual Studio Code yang disimpan. Untuk mempelajari selengkapnya, lihat pengaturan Visual Studio Code.
  • src/functions/: Lokasi default untuk semua fungsi dan pemicu dan pengikatan terkait.
  • test/: (Opsional) Berisi kasus pengujian aplikasi fungsi Anda.
  • .funcignore: (Opsional) Menyatakan file yang seharusnya tidak diterbitkan ke Azure. Biasanya, file ini berisi .vscode/ untuk mengabaikan pengaturan editor Anda, menguji/ mengabaikan kasus pengujian, dan local.settings.json mencegah pengaturan aplikasi lokal dipublikasikan.
  • host.json: Berisi opsi konfigurasi yang memengaruhi semua fungsi dalam instans aplikasi fungsi. File ini dipublikasikan ke Azure. Tidak semua opsi didukung saat berjalan secara lokal. Untuk mempelajari lebih lanjut, lihat host.json.
  • local.settings.json: Untuk menyimpan pengaturan aplikasi dan string koneksi yang digunakan saat berjalan secara lokal. File ini tidak diterbitkan ke Azure. Untuk mempelajari lebih lanjut, lihat local.settings.file.
  • package.json: Berisi opsi konfigurasi seperti daftar ketergantungan paket, titik masuk utama, dan skrip.

Manajemen paket

Manajemen paket yang efektif sangat penting untuk proyek Node.js Azure Functions. Bagian ini membahas manajemen ketergantungan, konfigurasi paket, dan praktik terbaik untuk memelihara ketergantungan aplikasi fungsi Anda.

Mengelola ketergantungan

Semua proyek Node.js Azure Functions menggunakan npm untuk manajemen paket. File Anda package.json mendefinisikan konfigurasi proyek, dependensi, dan skrip yang dibutuhkan untuk membangun dan menjalankan fungsi Anda.

Struktur dasar 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"
  }
}

Dependensi runtime vs. dependensi pengembangan

Pisahkan ketergantungan Anda dengan tepat:

Ketergantungan runtime (dependencies):

  • @azure/functions: Pustaka inti Azure Functions
  • Pustaka logika bisnis (lodash, axios, dan paket serupa)
  • Driver database (mongodb, mssql, dan paket serupa)
  • Azure SDK paket (@azure/storage-blob, @azure/cosmos, dan paket serupa)

Ketergantungan pengembangan (devDependencies):

  • Kompiler TypeScript dan definisi tipe
  • Kerangka kerja pengujian (Jest, Mocha)
  • Alat dan linter bangunan
  • Azure Functions Core Tools (untuk pengembangan lokal)

Paket khusus TypeScript

Untuk proyek TypeScript, sertakan ketergantungan pengembangan penting berikut:

{
  "devDependencies": {
    "@types/node": "^18.0.0",
    "typescript": "^4.0.0",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0"
  }
}

Keamanan dan pembaruan

Perbarui ketergantungan Anda secara rutin untuk mengatasi kerentanan keamanan:

# Check for outdated packages
npm outdated

# Update packages
npm update

# Audit for security issues
npm audit
npm audit fix

Menjalankan dan men-debug

Bagian ini membahas pengembangan lokal, teknik debugging, dan strategi pengujian untuk Node.js Azure Functions.

Konfigurasi pengembangan lokal

Prasyarat:

Langkah-langkah penyiapan:

  1. Pasang dependensi:

    npm install
    
  2. Membangun proyek TypeScript:

    npm run build
    
  3. Mulai runtime lokal:

    npm start
    # or directly:
    func start
    

Konfigurasi lingkungan

Konfigurasikan lingkungan pengembangan lokal Anda dengan menggunakan 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
  }
}

Pemecahan Masalah

Debugging Visual Studio Code:

Buat .vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Attach to Node Functions",
      "type": "node",
      "request": "attach",
      "port": 9229,
      "preLaunchTask": "func: host start"
    }
  ]
}

Buat .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}"
      }
    }
  ]
}

Penelusuran kesalahan baris perintah:

# Start with debugging enabled
func start --p <port>

# For TypeScript, ensure you build first
npm run build
func start --p 9229

Deployment

Bagian ini membahas strategi penerapan, integrasi CI/CD, dan praktik terbaik produksi untuk Node.js Azure Functions.

Metode penerapan

1. Penerapan Visual Studio Code:

  • Instal ekstensi Azure Functions.
  • Klik kanan aplikasi fungsi Anda di panel Azure.
  • Pilih Menyebarkan ke Aplikasi Fungsi.

2. Azure Functions 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. Penerapan Azure CLI:

# Deploy from local folder
az functionapp deployment source config-zip \
  --resource-group <ResourceGroupName> \
  --name <FunctionAppName> \
  --src <PathToZipFile>

Konfigurasi produksi

Pengaturan aplikasi di Azure:

Konfigurasikan variabel lingkungan untuk produksi:

  • WEBSITE_NODE_DEFAULT_VERSION: Atur ke ~18 atau ~20.
  • FUNCTIONS_WORKER_RUNTIME: Atur ke node.
  • String koneksi dan kunci API sebagai pengaturan aplikasi yang aman.
  • NODE_ENV: Atur ke production.

Pemicu dan pengikatan

Azure Functions menggunakan trigger untuk memulai eksekusi fungsi dan binding untuk menghubungkan kode Anda ke layanan lain seperti penyimpanan, antrean, dan database. Dalam model pemrograman Node.js, Anda mendeklarasikan binding secara berbeda tergantung pada versi model Anda.

Ada dua jenis pengikatan utama:

  • Pemicu (input yang memulai fungsi)
  • Input dan output (sumber data atau tujuan tambahan)

Untuk informasi selengkapnya tentang pemicu dan pengikatan yang tersedia, lihat Pemicu dan Pengikatan di Azure Functions.

Contoh: Pemicu Timer dengan Input Blob

Fungsi ini aktif setiap 10 menit, membaca dari Blob menggunakan input tambahan, dan mencatat konten 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}`);
    }
});

Fungsi ini dipicu setiap 10 menit, membaca dari Blob melalui konfigurasi binding, dan mencatat isi 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}`);
};

Contoh: Pemicu HTTP dengan Keluaran Antrean

Fungsi ini dipicu oleh permintaan HTTP, menulis pesan ke antrean penyimpanan, dan mengembalikan respons 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.`
        };
    }
});

Fungsi ini dipicu oleh permintaan HTTP, menulis pesan ke antrean penyimpanan, dan mengembalikan respons 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.`
    };
};

Objek app, trigger, input, dan output yang diekspor oleh @azure/functions modul menyediakan metode khusus jenis untuk sebagian besar jenis. Untuk semua jenis yang tidak didukung, generic metode disediakan untuk memungkinkan Anda menentukan konfigurasi secara manual. Metode generic juga dapat digunakan jika Anda ingin mengubah pengaturan bawaan yang disediakan oleh metode khusus untuk tipe tertentu.

Contoh berikut adalah fungsi yang dipicu HTTP sederhana menggunakan metode generik alih-alih metode khusus jenis.

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!` };
  },
});

::: zona akhir

Konteks pemanggilan

Setiap pemanggilan fungsi Anda menerima objek invocation context. Gunakan objek ini untuk membaca input, mengatur output, menulis ke log, dan mengakses berbagai metadata. Dalam model v3, Anda selalu meneruskan objek konteks sebagai argumen pertama ke handler Anda.

Objek ini context mencakup properti-properti berikut:

Properti Deskripsi
invocationId ID pemanggilan fungsi saat ini.
executionContext Lihat konteks eksekusi.
bindings Lihat pengikatan.
bindingData Metadata tentang input pemicu untuk pemanggilan ini, tidak termasuk nilainya sendiri. Misalnya, pemicu hub acara memiliki enqueuedTimeUtc properti.
traceContext Konteks untuk pelacakan terdistribusi. Untuk informasi selengkapnya, lihat Trace Context .
bindingDefinitions Konfigurasi input dan output Anda, seperti yang didefinisikan dalam function.json.
req Lihat HTTP request.
res Lihat respons HTTP.

context.executionContext

Objek context.executionContext memiliki properti berikut:

Properti Deskripsi
invocationId ID pemanggilan fungsi saat ini.
functionName Nama fungsi yang Anda gunakan. Nama folder yang berisi function.json file menentukan nama fungsi.
functionDirectory Folder yang berisi function.json file.
retryContext Lihat konteks pengulangan.

context.executionContext.retryContext

Objek context.executionContext.retryContext memiliki properti berikut:

Properti Deskripsi
retryCount Angka yang menunjukkan percobaan ulang saat ini.
maxRetryCount Jumlah maksimum kali eksekusi diulang. Nilai -1 berarti mencoba lagi tanpa batas.
exception Pengecualian yang menyebabkan pengulangan.

konteks.pengikatan

Gunakan context.bindings objek untuk membaca input atau mengatur output. Contoh berikut adalah pemicu antrean penyimpanan yang menggunakan context.bindings untuk menyalin blob input penyimpanan ke blob output penyimpanan. Konten pesan antrean menggantikan {queueTrigger} sebagai nama file yang akan disalin, dengan bantuan ekspresi pengikatan.

{
    "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;
};

konteks.selesai

Metode context.done ini tidak digunakan lagi. Sebelum Azure Functions mendukung fungsi asinkron, Anda memberi sinyal bahwa fungsi Anda sudah selesai dengan memanggil context.done():

module.exports = function (context, request) {
  context.log("this pattern is now deprecated");
  context.done();
};

Hapus panggilan ke context.done(). Tandai await fungsi Anda sebagai asinkron agar mengembalikan janji (meskipun Anda tidak melakukan apa-apa). Segera setelah fungsi Anda selesai (dengan kata lain, janji yang dikembalikan telah diselesaikan), model v3 mengetahui bahwa fungsi Anda telah selesai.

module.exports = async function (context, request) {
  context.log("you don't need context.done or an awaited call");
};

Setiap pemanggilan fungsi Anda menerima objek invocation context. Objek ini berisi informasi tentang pemanggilan Anda dan metode pencatatan. Dalam model v4, Anda biasanya meneruskan context objek sebagai argumen kedua ke handler Anda.

Kelas InvocationContext ini mencakup properti berikut:

Properti Deskripsi
invocationId ID pemanggilan fungsi saat ini.
functionName Nama fungsi.
extraInputs Digunakan untuk mendapatkan nilai input tambahan. Untuk informasi selengkapnya, lihat input dan output tambahan.
extraOutputs Digunakan untuk mengatur nilai output tambahan. Untuk informasi selengkapnya, lihat input dan output tambahan.
retryContext Lihat konteks pengulangan.
traceContext Konteks untuk pelacakan terdistribusi. Untuk informasi selengkapnya, lihat Trace Context .
triggerMetadata Metadata tentang input pemicu untuk pemanggilan ini, tidak termasuk nilai itu sendiri. Misalnya, pemicu hub acara memiliki enqueuedTimeUtc properti.
options Opsi yang digunakan saat mendaftarkan fungsi, setelah divalidasi dan default ditentukan secara eksplisit.

Coba ulang konteks

Objek retryContext memiliki properti berikut:

Properti Deskripsi
retryCount Angka yang menunjukkan percobaan ulang saat ini.
maxRetryCount Jumlah maksimum kali eksekusi diulang. Nilai -1 berarti mencoba lagi tanpa batas.
exception Pengecualian yang menyebabkan pengulangan.

Untuk informasi selengkapnya, lihat retry-policies .

Logging

Di Azure Functions, gunakan context.log() untuk menulis log. Azure Functions terintegrasi dengan Azure Application Insights untuk menangkap log aplikasi fungsi Anda dengan lebih baik. Application Insights, bagian dari Azure Monitor, menyediakan fasilitas untuk pengumpulan, penyajian visual, dan analisis log aplikasi dan output jejak Anda. Untuk mempelajari selengkapnya, lihat monitoring Azure Functions.

Catatan

Jika Anda menggunakan metode alternatif Node.js console.log , log tingkat aplikasi dilacak tetapi tidak dikaitkan dengan fungsi tertentu. Gunakan context untuk pencatatan sebagai pengganti console agar semua log dikaitkan dengan fungsi tertentu.

Contoh berikut menulis log pada level "informasi" bawaan, termasuk ID panggilan:

context.log(`Something has happened. Invocation ID: "${context.invocationId}"`);

Tingkat Catatan

Selain metode default context.log , gunakan metode berikut untuk menulis log pada level tertentu:

Metode Deskripsi
context.log.error() Menulis kejadian tingkat kesalahan ke dalam log.
context.log.warn() Menulis peristiwa tingkat peringatan ke log.
context.log.info() Menulis peristiwa tingkat informasi ke log.
context.log.verbose() Menulis peristiwa tingkat jejak ke log.
Metode Deskripsi
context.trace() Menulis peristiwa tingkat jejak ke log.
context.debug() Menulis peristiwa tingkat debug ke log.
context.info() Menulis peristiwa tingkat informasi ke log.
context.warn() Menulis peristiwa tingkat peringatan ke log.
context.error() Menulis kejadian tingkat kesalahan ke dalam log.

Mengonfigurasi tingkat log

Functions memungkinkan Anda menentukan tingkat ambang batas untuk pelacakan dan melihat log. Untuk mengatur ambang batas, gunakan logging.logLevel properti dalam host.json file. Properti ini memungkinkan Anda menentukan level default untuk semua fungsi atau ambang batas untuk setiap fungsi individual. Untuk mempelajari selengkapnya, lihat Cara mengonfigurasi pemantauan untuk Azure Functions.

Melacak data kustom

Secara bawaan, Azure Functions menuliskan keluaran dalam bentuk jejak ke Application Insights. Untuk kontrol lebih lanjut, gunakan Application Insights Node.js SDK untuk mengirim log kustom, metrik, dan dependensi ke instance Application Insights Anda.

Catatan

Metode dalam Application Insights Node.js SDK dapat berubah dari waktu ke waktu. Mungkin ada perbedaan sintaksis kecil dari contoh yang ditunjukkan di sini. Untuk contoh penggunaan API terbaru, lihat dokumentasi Application Insights Node.js SDK.

Untuk pelacakan terdistribusi dalam model pemrograman Node.js v4, gunakan paket sebagai @azure/functions-opentelemetry-instrumentation pengganti Application Insights SDK. Paket ini menyediakan instrumentasi otomatis berbasis OpenTelemetry untuk Azure Functions. Untuk informasi selengkapnya, lihat repositori GitHub Instrumentasi Azure Functions OpenTelemetry untuk Node.js.

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,
  });
};

Parameter tagOverrides menetapkan operation_Id ke ID pemanggilan fungsi. Pengaturan ini memungkinkan Anda mengkorelasikan semua log yang dihasilkan secara otomatis dan khusus untuk pemanggilan fungsi tertentu.

Pemicu HTTP

Pemicu HTTP dan webhook menggunakan objek permintaan dan respons untuk mewakili pesan HTTP.

Pemicu HTTP dan webhook menggunakan HttpRequest dan HttpResponse objek untuk mewakili pesan HTTP. Kelas mewakili subset dari fetch standard, menggunakan paket undici dari Node.js.

Permintaan HTTP

Akses permintaan dengan beberapa cara:

  • Sebagai argumen kedua untuk fungsi Anda:

    module.exports = async function (context, request) {
        context.log(`Http function processed request for url "${request.url}"`);
    

  • Dari context.req properti:

    module.exports = async function (context, request) {
        context.log(`Http function processed request for url "${context.req.url}"`);
    

  • Dari binding input yang disebutkan: Opsi ini bekerja sama seperti binding non-HTTP lainnya. Nama pengikatan di function.json harus cocok dengan kunci pada context.bindings, atau "request1" dalam contoh berikut:

    {
      "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}"`);
    

Objek HttpRequest memiliki properti berikut:

Properti Tipe Deskripsi
method string Metode permintaan HTTP yang digunakan untuk memanggil fungsi ini.
url string URL Permintaan.
headers Record<string, string> Header permintaan HTTP. Objek ini peka huruf besar/kecil. Gunakan request.getHeader('header-name') sebagai gantinya, yang tidak sensitif huruf besar/kecil.
query Record<string, string> Kueri kunci parameter string dan nilai dari URL.
params Record<string, string> Kunci dan nilai parameter rute.
user HttpRequestUser \| null Objek yang mewakili pengguna yang masuk, baik melalui autentikasi Functions, Autentikasi SWA, atau null ketika tidak ada pengguna tersebut yang masuk.
body Buffer \| string \| any Jika jenis media adalah "application/octet-stream" atau "multipart/*", body adalah Buffer. Jika nilainya adalah string yang dapat diurai JSON, body adalah objek yang diurai. Jika tidak, body adalah string.
rawBody string Badan sebagai string. Terlepas dari namanya, properti ini tidak mengembalikan Buffer.
bufferBody Buffer Tubuh sebagai penyangga.

Anda dapat mengakses permintaan tersebut sebagai argumen pertama untuk handler Anda pada fungsi yang dipicu HTTP.

async (request, context) => {
    context.log(`Http function processed request for url "${request.url}"`);

Objek HttpRequest memiliki properti berikut:

Properti Tipe Deskripsi
method string Metode permintaan HTTP yang digunakan untuk memanggil fungsi ini.
url string URL Permintaan.
headers Headers Header permintaan HTTP.
query URLSearchParams Kueri kunci parameter string dan nilai dari URL.
params Record<string, string> Kunci dan nilai parameter rute.
user HttpRequestUser \| null Objek yang mewakili pengguna yang masuk, baik melalui autentikasi Functions, Autentikasi SWA, atau null ketika tidak ada pengguna tersebut yang masuk.
body ReadableStream \| null Badan sebagai stream yang dapat dibaca.
bodyUsed boolean Boolean yang menunjukkan apakah isi sudah dibaca.

Untuk mengakses isi permintaan atau respons, gunakan metode berikut:

Metode Tipe Kembali
arrayBuffer() Promise<ArrayBuffer>
blob() Promise<Blob>
formData() Promise<FormData>
json() Promise<unknown>
text() Promise<string>

Catatan

Anda hanya bisa menjalankan fungsi tubuh sekali saja. Panggilan berikutnya akan terselesaikan dengan string kosong atau ArrayBuffer.

Respons HTTP

Anda dapat mengatur respons dengan beberapa cara. Misalnya, Anda dapat menggunakan:

  • Atur context.res properti:

    module.exports = async function (context, request) {
        context.res = { body: `Hello, world!` };
    

  • Kembalikan respons: Jika fungsi Anda asinkron dan Anda mengatur nama pengikatan ke $return di , function.jsonAnda dapat mengembalikan respons secara langsung alih-alih mengaturnya pada context.

    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
    
    module.exports = async function (context, request) {
        return { body: `Hello, world!` };
    

  • Atur binding output yang disebutkan: Opsi ini bekerja sama seperti binding non-HTTP lainnya. Nama pengikatan di function.json harus cocok dengan kunci pada context.bindings, atau "respons1" dalam contoh berikut:

    {
      "type": "http",
      "direction": "out",
      "name": "response1"
    }
    
    module.exports = async function (context, request) {
        context.bindings.response1 = { body: `Hello, world!` };
    

  • Panggilan context.res.send(): Opsi ini tidak digunakan lagi. Aplikasi ini secara implisit memanggil context.done() dan Anda tidak bisa menggunakannya dalam fungsi asinkron.

    module.exports = function (context, request) {
        context.res.send(`Hello, world!`);
    

Jika Anda membuat objek baru saat mengatur respons, objek tersebut harus cocok dengan HttpResponseSimple antarmuka, yang memiliki properti berikut:

Properti Tipe Deskripsi
headers Record<string, string> (pilihan) Header respons HTTP
cookies Cookie[] (pilihan) Cookie respons HTTP.
body any (pilihan) Isi respons HTTP.
statusCode number (pilihan) kode status respons HTTP. Jika tidak diatur, akan default ke 200.
status number (pilihan) Sama seperti statusCode. Properti ini diabaikan jika statusCode diatur.

Anda juga dapat mengubah objek context.res tanpa menimpanya. Objek default context.res menggunakan HttpResponseFull antarmuka, yang mendukung metode berikut selain HttpResponseSimple properti:

Metode Deskripsi
status() Mengatur status.
setHeader() Mengatur kolom header. CATATAN:res.set() dan res.header() juga didukung serta melakukan hal yang sama.
getHeader() Mengambil kolom header. CATATAN:res.get() juga didukung dan berfungsi sama.
removeHeader() Menghapus header.
type() Mengatur tajuk "content-type".
send() Metode ini tidak digunakan lagi. Ini mengatur isi dan panggilan context.done() untuk menunjukkan fungsi sinkronisasi selesai. CATATAN:res.end() juga didukung dan berfungsi sama.
sendStatus() Metode ini tidak digunakan lagi. Ini mengatur kode status dan panggilan context.done() untuk menunjukkan fungsi sinkronisasi selesai.
json() Metode ini tidak digunakan lagi. Ini mengatur "jenis konten" ke "application/json", mengatur isi, dan panggilan context.done() untuk menunjukkan fungsi sinkronisasi selesai.

Anda dapat mengatur respons dengan beberapa cara. Misalnya, Anda dapat menggunakan:

  • Antarmuka sederhana dengan tipe HttpResponseInit: Opsi ini adalah cara paling ringkas untuk mengembalikan respons.

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

Antarmuka HttpResponseInit memiliki properti berikut:

Properti Tipe Deskripsi
body BodyInit (pilihan) Isi respons HTTP sebagai salah satu dari ArrayBuffer, AsyncIterable<Uint8Array>, Blob, FormData, Iterable<Uint8Array>, NodeJS.ArrayBufferView, URLSearchParams, null, atau string.
jsonBody any (pilihan) Isi Respons HTTP yang dapat diserialisasikan JSON. Jika ditentukan, properti HttpResponseInit.body diabaikan untuk menggunakan properti ini.
status number (pilihan) kode status respons HTTP. Jika tidak diatur, akan default ke 200.
headers HeadersInit (pilihan) Header respons HTTP
cookies Cookie[] (pilihan) Cookie respons HTTP.
  • Sebagai kelas dengan jenis HttpResponse: Opsi ini menyediakan metode pembantu untuk membaca dan memodifikasi berbagai bagian respons seperti header.

    const response = new HttpResponse({ body: `Hello, world!` });
    response.headers.set("content-type", "application/json");
    return response;
    

Kelas HttpResponse menerima opsional HttpResponseInit sebagai argumen untuk konstruktornya dan memiliki properti berikut:

Properti Tipe Deskripsi
status number kode status respons HTTP.
headers Headers Header respons HTTP
cookies Cookie[] Cookie respons HTTP.
body ReadableStream | null Badan sebagai stream yang dapat dibaca.
bodyUsed boolean Boolean yang menunjukkan apakah isi sudah dibaca.

Aliran HTTP

Aliran HTTP adalah fitur yang memudahkan pemrosesan data besar, mengalirkan respons OpenAI, mengirimkan konten dinamis, dan mendukung skenario HTTP inti lainnya. Ini memungkinkan Anda melakukan streaming permintaan ke dan respons dari titik akhir HTTP di aplikasi fungsi Node.js Anda. Gunakan aliran HTTP dalam skenario di mana aplikasi Anda memerlukan pertukaran real time dan interaksi antara klien dan server melalui HTTP. Anda juga dapat menggunakan aliran HTTP untuk mendapatkan performa dan keandalan terbaik untuk aplikasi Anda saat menggunakan HTTP.

Penting

Aliran HTTP tidak didukung dalam model v3. Tingkatkan ke model v4 untuk menggunakan fitur streaming HTTP. Jenis HttpRequest dan HttpResponse yang ada dalam model pemrograman v4 sudah mendukung berbagai cara untuk menangani badan pesan, termasuk sebagai stream.

Prasyarat

Mengaktifkan aliran

Gunakan langkah-langkah ini untuk mengaktifkan aliran HTTP di aplikasi fungsi Anda di Azure dan di proyek lokal Anda:

  1. Jika Anda berencana untuk melakukan streaming data dalam jumlah besar, ubah pengaturan FUNCTIONS_REQUEST_BODY_SIZE_LIMIT di Azure. Ukuran bodi maksimum default yang diizinkan adalah 104857600, yang membatasi permintaan Anda hingga sekitar 100 MB.

  2. Untuk pengembangan lokal, tambahkan FUNCTIONS_REQUEST_BODY_SIZE_LIMIT juga ke file local.settings.json.

  3. Tambahkan kode berikut ke aplikasi Anda dalam file apa pun yang disertakan oleh bidang utama Anda.

    const { app } = require("@azure/functions");
    
    app.setup({ enableHttpStream: true });
    

Contoh Stream

Contoh berikut menunjukkan fungsi HTTP yang dipicu yang menerima data melalui permintaan HTTP POST. Fungsi ini mengalirkan data ini ke file output yang ditentukan:

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!' };
    },
});

Contoh berikut menunjukkan fungsi HTTP yang dipicu yang mengalirkan konten file sebagai respons terhadap permintaan HTTP GET yang masuk:

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 };
    },
});

Untuk aplikasi contoh siap pakai yang menggunakan stream, lihat contoh ini di GitHub.

Pertimbangan streaming

  • Gunakan request.body untuk mendapatkan manfaat maksimal dari menggunakan streaming. Anda masih bisa menggunakan metode seperti request.text(), yang selalu mengembalikan bodi sebagai string.

Hook

Model v3 tidak mendukung hook. Tingkatkan ke model v4 untuk menggunakan hook.

Gunakan kait untuk mengeksekusi kode di titik yang berbeda dalam siklus hidup Azure Functions. Urutan Anda mendaftarkan hook menentukan urutan eksekusinya. Anda dapat mendaftarkan hook dari file apa pun di aplikasi Anda. Ada dua cakupan hook: tingkat "app" dan tingkat "invocation".

Kait pemanggilan

Hook invocation berjalan sekali setiap pemanggilan fungsi Anda. Hook preInvocation berjalan sebelum fungsi berjalan, dan postInvocation hook berjalan setelah fungsi berjalan. Secara default, hook Anda akan dijalankan untuk semua jenis trigger, tetapi Anda juga dapat memfilter berdasarkan jenis. Contoh berikut menunjukkan cara mendaftarkan kait pemanggilan dan memfilter berdasarkan jenis pemicu:

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']
});

Argumen pertama untuk pengelola kait adalah objek konteks yang spesifik untuk jenis kait tersebut.

Objek PreInvocationContext memiliki properti berikut:

Properti Deskripsi
inputs Argumen yang Anda teruskan ke invokasi.
functionHandler Fungsi handler untuk pemanggilan. Perubahan pada nilai ini memengaruhi fungsi itu sendiri.
invocationContext Objek konteks pemanggilan yang diteruskan ke fungsi.
hookData Tempat yang disarankan untuk menyimpan dan berbagi data antara hook dalam cakupan yang sama. Gunakan nama properti unik agar tidak bertentangan dengan data hook lain.

Objek PostInvocationContext memiliki properti berikut:

Properti Deskripsi
inputs Argumen yang Anda teruskan ke invokasi.
result Hasil fungsi. Perubahan pada nilai ini memengaruhi hasil keseluruhan fungsi.
error Kesalahan yang dilemparkan oleh fungsi, atau null/undefined jika tidak ada kesalahan. Perubahan pada nilai ini memengaruhi hasil keseluruhan fungsi.
invocationContext Objek konteks pemanggilan yang diteruskan ke fungsi.
hookData Tempat yang disarankan untuk menyimpan dan berbagi data antara hook dalam cakupan yang sama. Gunakan nama properti unik agar tidak bertentangan dengan data hook lain.

Pengait Aplikasi

Runtime menjalankan hook aplikasi sekali untuk setiap instans aplikasi Anda. Ia menjalankan appStart hook saat startup dan appTerminate hook saat terminasi. Kait penghentian aplikasi memiliki waktu terbatas untuk dijalankan dan tidak dijalankan dalam semua skenario.

Runtime Azure Functions saat ini tidak mendukung log konteks di luar pemanggilan. Gunakan paket npm Application Insights untuk mencatat data selama kait tingkat aplikasi.

Contoh berikut mendaftarkan hook aplikasi:

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 }));
});

Argumen pertama untuk pengelola kait adalah objek konteks yang spesifik untuk jenis kait tersebut.

Objek AppStartContext memiliki properti berikut:

Properti Deskripsi
hookData Tempat yang disarankan untuk menyimpan dan berbagi data antara hook dalam cakupan yang sama. Gunakan nama properti unik agar tidak bertentangan dengan data hook lain.

Objek AppTerminateContext memiliki properti berikut:

Properti Deskripsi
hookData Tempat yang disarankan untuk menyimpan dan berbagi data antara hook dalam cakupan yang sama. Gunakan nama properti unik agar tidak bertentangan dengan data hook lain.

Praktik Terbaik Hook

Saat menggunakan hook di Azure Functions Anda, pertimbangkan praktik terbaik berikut:

Pertimbangan performa

  • Jaga waktu eksekusi hook seminimal mungkin untuk menghindari memengaruhi performa fungsi.
  • Gunakan operasi asinkron jika memungkinkan untuk mencegah blokir.
  • Pertimbangkan overhead dari hook saat memproses permintaan dalam volume tinggi.

Penanganan kesalahan

  • Selalu sertakan penanganan kesalahan yang benar dalam hook Anda.
  • Jangan biarkan kegagalan hook menyebabkan kegagalan fungsi kecuali benar-benar diperlukan.
  • Catat hook error secara tepat untuk keperluan debugging.

Berbagi data

  • Gunakan hookData untuk berbagi informasi antara hook pra dan pasca pemanggilan.
  • Gunakan nama properti unik untuk menghindari konflik dengan hook lain.
  • Bersihkan data hook saat tidak lagi diperlukan untuk mencegah kebocoran memori.

Penyaringan

  • Gunakan filter tipe trigger untuk memastikan hook hanya berjalan untuk fungsi yang relevan.
  • Spesifiklah dengan filter Anda untuk mengoptimalkan performa.

Penskalaan dan konkurensi

Secara default, Azure Functions secara otomatis memantau beban pada aplikasi Anda dan membuat lebih banyak instans host untuk Node.js sesuai kebutuhan. Azure Functions menggunakan ambang batas bawaan (tidak dapat dikonfigurasi pengguna) untuk berbagai tipe trigger guna menentukan kapan menambahkan instance, seperti usia pesan dan ukuran antrean untuk QueueTrigger. Untuk informasi selengkapnya, lihat Cara kerja paket Konsumsi dan Premium.

Perilaku penskalaan ini cukup tersedia untuk sejumlah aplikasi Node.js. Untuk aplikasi yang dibatasi oleh CPU, Anda dapat meningkatkan performa lebih jauh dengan menggunakan beberapa proses pekerja multi-bahasa. Anda dapat meningkatkan jumlah proses pekerja per host dari default 1 hingga maksimal 10 dengan menggunakan pengaturan aplikasi FUNCTIONS_WORKER_PROCESS_COUNT . Azure Functions kemudian mencoba mendistribusikan pemanggilan fungsi simultan secara merata di seluruh pekerja ini. Perilaku ini membuatnya lebih kecil kemungkinan fungsi intensif CPU memblokir fungsi lain agar tidak berjalan. Pengaturan ini berlaku untuk setiap host yang Azure Functions buat saat menskalakan aplikasi Anda untuk memenuhi permintaan.

Peringatan

FUNCTIONS_WORKER_PROCESS_COUNT Gunakan pengaturan dengan hati-hati. Beberapa proses yang berjalan dalam instans yang sama dapat menyebabkan perilaku yang tidak dapat diprediksi dan meningkatkan waktu muat fungsi. Jika Anda menggunakan pengaturan ini, menjalankan dari file paket dapat mengimbangi kekurangan tersebut.

Versi node

Anda dapat melihat versi saat ini yang digunakan oleh runtime dengan melakukan log process.version dari fungsi mana pun. Lihat supported versions untuk daftar versi Node.js yang didukung oleh setiap model pemrograman.

Mengatur versi Node

Cara Anda meningkatkan versi Node.js bergantung pada OS tempat aplikasi fungsi Anda berjalan.

Saat berjalan di Windows, atur versi Node.js dengan menggunakan WEBSITE_NODE_DEFAULT_VERSION pengaturan aplikasi. Perbarui pengaturan ini baik dengan menggunakan Azure CLI atau di portal Azure.

Untuk informasi selengkapnya tentang versi Node.js, lihat Versi yang didukung.

Sebelum meningkatkan versi Node.js, pastikan aplikasi fungsi Anda berjalan pada versi terbaru runtime Azure Functions. Jika Anda perlu meningkatkan versi runtime, lihat Migrasikan aplikasi dari Azure Functions versi 3.x ke versi 4.x.

Jalankan perintah Azure CLI az functionapp config appsettings set untuk memperbarui versi Node.js untuk aplikasi fungsi Anda yang berjalan di Windows:

az functionapp config appsettings set  --settings WEBSITE_NODE_DEFAULT_VERSION=~22 \
 --name <FUNCTION_APP_NAME> --resource-group <RESOURCE_GROUP_NAME>

Perintah ini mengatur WEBSITE_NODE_DEFAULT_VERSION pengaturan aplikasi ke versi ~22LTS yang didukung.

Setelah Anda melakukan perubahan, aplikasi fungsi Anda akan di-restart. Untuk informasi lebih lanjut tentang dukungan Functions pada Node.js, lihat Kebijakan dukungan runtime bahasa.

Variabel lingkungan

Gunakan variabel lingkungan untuk mengelola rahasia operasional, seperti string koneksi, kunci, dan endpoint. Gunakan juga untuk pengaturan lingkungan, seperti pembuatan profil variabel. Tambahkan variabel lingkungan di lingkungan lokal dan cloud Anda, lalu akses melalui process.env kode fungsi Anda.

Contoh berikut mencatat WEBSITE_SITE_NAME variabel lingkungan:

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"]}`);
}

Di lingkungan pengembangan lokal

Saat Anda menjalankan secara lokal, proyek fungsi Anda menyertakan local.settings.json file, tempat Anda menyimpan variabel lingkungan di Values objek.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "CUSTOM_ENV_VAR_1": "hello",
    "CUSTOM_ENV_VAR_2": "world"
  }
}

Di lingkungan cloud Azure

Saat Anda menjalankan di Azure, aplikasi fungsi memungkinkan Anda mengatur dan menggunakan pengaturan Aplikasi, seperti string koneksi layanan, dan mengekspos pengaturan ini sebagai variabel lingkungan selama eksekusi.

Ada beberapa cara yang dapat Anda tambahkan, perbarui, dan hapus pengaturan aplikasi fungsi:

Perubahan pada pengaturan aplikasi fungsi mengharuskan aplikasi fungsi Anda dimulai ulang.

Variabel lingkungan pekerja

Node.js memiliki beberapa variabel lingkungan Functions yang spesifik untuknya:

languageWorkers__node__arguments

Gunakan pengaturan ini untuk menentukan argumen kustom saat memulai proses Node.js Anda. Biasanya, Anda menggunakannya secara lokal untuk memulai worker dalam mode debug, tetapi Anda juga bisa menggunakannya di Azure jika Anda membutuhkan argumen kustom.

Peringatan

Jika memungkinkan, hindari menggunakan languageWorkers__node__arguments di Azure karena dapat berdampak negatif pada waktu cold start. Alih-alih menggunakan pekerja yang sudah dipanaskan, runtime harus memulai pekerja baru dari awal dengan menggunakan argumen kustom Anda.

Pencatatan level log Pekerja

Gunakan pengaturan ini untuk menyesuaikan level log default untuk log pekerja spesifik Node.js. Secara default, hanya log peringatan atau kesalahan yang ditampilkan, tetapi Anda dapat mengaturnya ke information atau debug untuk membantu mendiagnosis masalah dengan pekerja Node.js. Untuk informasi selengkapnya, lihat mengonfigurasi tingkat log.

Modul ECMAScript (pratinjau)

Catatan

Modul ECMAScript saat ini merupakan fitur pratinjau di Node.js 14 atau lebih tinggi di Azure Functions.

Modul ECMAScript (modul ES) adalah sistem modul standar resmi baru untuk Node.js. Sejauh ini, sampel kode dalam artikel ini menggunakan sintaks CommonJS. Saat menjalankan Azure Functions di Node.js 14 atau lebih tinggi, Anda dapat memilih untuk menulis fungsi Anda menggunakan sintaks modul ES.

Untuk menggunakan modul ES di suatu fungsi, ubah nama filenya untuk menggunakan ekstensi .mjs. Contoh file index.mjs berikut adalah fungsi yang dipicu HTTP yang menggunakan sintaks modul ES untuk mengimpor pustaka uuid dan mengembalikan nilai.

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,
});

Mengonfigurasi titik entri fungsi

Gunakan properti function.json dan scriptFileentryPoint mengatur lokasi serta nama fungsi yang Anda ekspor. Saat Anda menggunakan TypeScript, Anda membutuhkan properti tersebut scriptFile dan properti tersebut harus mengarah ke JavaScript yang telah dikompilasi.

Menggunakan scriptFile

Secara default, fungsi JavaScript berjalan dari index.js. File ini berbagi direktori induk yang sama dengan file terkait function.json .

Gunakan scriptFile untuk mengatur struktur folder Anda. Contoh berikut menunjukkan satu cara untuk mengatur folder Anda:

<project_root>/
 | - node_modules/
 | - myFirstFunction/
 | | - function.json
 | - lib/
 | | - sayHello.js
 | - host.json
 | - package.json

File function.json untuk myFirstFunction harus menyertakan properti scriptFile yang menunjuk ke file dengan fungsi yang diekspor untuk dijalankan.

{
  "scriptFile": "../lib/sayHello.js",
  "bindings": [
    ...
  ]
}

Menggunakan entryPoint

Dalam model v3, Anda harus mengekspor fungsi dengan menggunakan module.exports agar fungsi tersebut dapat ditemukan dan dijalankan. Secara default, fungsi yang berjalan saat dipicu adalah satu-satunya ekspor dari file tersebut. Bisa juga berupa ekspor bernama run atau ekspor bernama index. Contoh berikut menetapkan entryPointfunction.json ke nilai kustom, "logHello":

{
  "entryPoint": "logHello",
  "bindings": [
    ...
  ]
}
async function logHello(context) {
  context.log("Hello, world!");
}

module.exports = { logHello };

Rekomendasi

Bagian ini menjelaskan beberapa pola berdampak untuk aplikasi Node.js yang sebaiknya Anda ikuti.

Pilih paket App Service tunggal vCPU

Saat Anda membuat aplikasi fungsi yang menggunakan paket App Service, pilih paket dengan satu vCPU daripada paket dengan beberapa vCPU. Saat ini, Functions menjalankan Node.js fungsi lebih efisien pada VM single-vCPU, dan menggunakan VM yang lebih besar tidak memberikan peningkatan performa yang diharapkan. Jika diperlukan, Anda dapat meningkatkan skala secara horizontal dengan menambahkan lebih banyak instance VM vCPU tunggal, atau mengaktifkan penskalaan otomatis. Untuk informasi selengkapnya, lihat Skalakan jumlah instans secara manual atau otomatis.

Jalankan dari file paket

Ketika Anda mengembangkan Azure Functions dalam model hosting tanpa server, cold start merupakan kenyataan. Cold start mengacu pada pertama kali aplikasi fungsi Anda dimulai setelah periode tidak aktif, membutuhkan waktu lebih lama untuk memulai. Untuk aplikasi Node.js dengan pohon dependensi yang besar khususnya, cold start dapat menjadi signifikan. Untuk mempercepat proses cold start, jalankan fungsi Anda sebagai file paket jika memungkinkan. Banyak metode penerapan menggunakan model ini secara bawaan, tetapi jika Anda mengalami waktu cold start yang lama, pastikan Anda menjalankannya dengan cara ini.

Gunakan async dan await

Saat menulis Azure Functions dengan Node.js, tulislah kode dengan menggunakan kata kunci async dan await. Menulis kode dengan menggunakan async dan await alih-alih callback atau .then dan .catch dengan Promise membantu Anda menghindari dua masalah umum:

  • Melemparkan pengecualian tak tertangkap yang menghentikan proses Node.js dan dapat memengaruhi eksekusi fungsi lain.
  • Perilaku tak terduga, seperti log yang hilang dari context.log, yang disebabkan oleh panggilan asinkron yang tidak diantisipasi dengan benar.

Dalam contoh berikut, metode fs.readFile asinkron dipanggil dengan fungsi panggilan balik kesalahan-pertama sebagai parameter kedua. Kode ini menyebabkan kedua masalah yang disebutkan sebelumnya. Pengecualian yang tidak secara eksplisit ditangani dalam cakupan yang benar dapat menghentikan seluruh proses (masalah #1). Mengembalikan tanpa memastikan callback selesai berarti respons HTTP terkadang memiliki isi kosong (masalah #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 };
    },
});

Dalam contoh berikut, metode fs.readFile asinkron dipanggil dengan fungsi panggilan balik kesalahan-pertama sebagai parameter kedua. Kode ini menyebabkan kedua masalah yang telah disebutkan sebelumnya. Pengecualian yang tidak secara eksplisit terdeteksi dalam lingkup yang benar dapat menyebabkan seluruh proses crash (masalah #1). Memanggil metode yang sudah tidak digunakan context.done() di luar lingkup callback dapat menandakan fungsi selesai sebelum file dibaca (masalah #2). Di contoh ini, memanggil context.done() terlalu dini menghasilkan entri log menghilang, dimulai dengan 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();
};

Gunakan async kata kunci dan await untuk membantu menghindari kedua masalah ini. Sebagian besar API dalam ekosistem Node.js sekarang mendukung janji dalam bentuk tertentu. Misalnya, mulai dari versi 14, Node.js menyediakan fs/promises API untuk menggantikan fs API callback.

Dalam contoh berikut, setiap pengecualian yang tidak tertangani yang terjadi selama eksekusi fungsi hanya akan menyebabkan kegagalan pada pemanggilan individu yang memunculkan pengecualian. Kata await kunci berarti bahwa langkah-langkah berikut readFile hanya dijalankan setelah selesai.

// 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;
        }
    },
});

Saat Anda menggunakan async dan await, Anda tidak perlu memanggil callback 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}`);
};

Pecahkan masalah

Lihat panduan Pemecahan Masalah Node.js.

Langkah berikutnya

Untuk informasi selengkapnya, lihat sumber daya berikut: