Panduan pengembang Node.js Azure Functions

Panduan ini adalah pengantar untuk mengembangkan Azure Functions menggunakan JavaScript atau TypeScript. Artikel ini mengasumsikan bahwa Anda telah membaca panduan pengembang Azure Functions.

Penting

Konten artikel ini berubah berdasarkan pilihan model pemrograman Node.js Anda di pemilih di bagian atas halaman ini. Versi yang Anda pilih harus cocok dengan versi @azure/functions paket npm yang Anda gunakan di aplikasi Anda. Jika Anda tidak memiliki paket yang tercantum di Anda package.json, defaultnya adalah v3. Pelajari selengkapnya tentang perbedaan antara v3 dan v4 dalam panduan migrasi.

Sebagai pengembang Node.js, Anda mungkin juga tertarik dengan salah satu artikel berikut:

Memulai Konsep Pembelajaran terpandu

Pertimbangan

  • Model pemrograman Node.js tidak boleh dikacaukan dengan runtime Azure Functions:
    • Model pemrograman: Menentukan bagaimana Anda menulis kode Anda dan khusus untuk JavaScript dan TypeScript.
    • Runtime: Menentukan perilaku yang mendasari Azure Functions dan dibagikan di semua bahasa.
  • Versi model pemrograman sangat terkait dengan versi @azure/functions paket npm. Versi ini di-versi secara independen dari runtime. Baik runtime maupun model pemrograman menggunakan nomor 4 sebagai versi utama terbarunya, tetapi itu kebetulan.
  • Anda tidak dapat mencampur model pemrograman v3 dan v4 di aplikasi fungsi yang sama. Segera setelah Anda mendaftarkan satu fungsi v4 di aplikasi Anda, fungsi v3 apa pun yang terdaftar di file function.json diabaikan.

Versi yang didukung

Tabel berikut ini memperlihatkan setiap versi model pemrograman Node.js bersama dengan versi runtime Dan Node.js Azure Functions yang didukung.

Versi Model Pemrograman Tingkat Dukungan Versi Runtime Functions Versi Node.js Deskripsi
4.x GA 4.25+ 20.x, 18.x Mendukung struktur file yang fleksibel dan pendekatan yang berpusat pada kode untuk pemicu dan pengikatan.
3.x GA 4.x 20.x, 18.x, 16.x, 14.x Memerlukan struktur file tertentu dengan pemicu dan pengikatan Anda yang dideklarasikan dalam file "function.json"
2.x n/a 3.x 14.x, 12.x, 10.x Mencapai akhir dukungan pada 13 Desember 2022. Lihat Versi Fungsi untuk informasi selengkapnya.
1.x n/a 2.x 10.x, 8.x Mencapai akhir dukungan pada 13 Desember 2022. Lihat Versi Fungsi untuk informasi selengkapnya.

Struktur folder

Struktur folder yang diperlukan untuk proyek JavaScript terlihat seperti 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) Mendeklarasikan file yang seharusnya tidak dipublikasikan ke Azure. Biasanya, file ini berisi .vscode/ untuk mengabaikan pengaturan editor, pengujian/ untuk mengabaikan kasus pengujian, dan local.settings.json untuk mencegah pengaturan aplikasi lokal diterbitkan.
  • 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: Digunakan untuk menyimpan pengaturan aplikasi dan string koneksi saat berjalan secara lokal. File ini tidak dipublikasikan ke Azure. Untuk mempelajari lebih lanjut, lihat local.settings.file.
  • package.json: Berisi opsi konfigurasi seperti daftar dependensi paket, titik masuk utama, dan skrip.

Struktur folder yang direkomendasikan untuk proyek JavaScript terlihat seperti 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) Mendeklarasikan file yang seharusnya tidak dipublikasikan ke Azure. Biasanya, file ini berisi .vscode/ untuk mengabaikan pengaturan editor, pengujian/ untuk mengabaikan kasus pengujian, dan local.settings.json untuk mencegah pengaturan aplikasi lokal diterbitkan.
  • 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: Digunakan untuk menyimpan pengaturan aplikasi dan string koneksi saat berjalan secara lokal. File ini tidak dipublikasikan ke Azure. Untuk mempelajari lebih lanjut, lihat local.settings.file.
  • package.json: Berisi opsi konfigurasi seperti daftar dependensi paket, titik masuk utama, dan skrip.

Mendaftarkan fungsi

Model v3 mendaftarkan fungsi berdasarkan keberadaan dua file. Pertama, Anda memerlukan file yang function.json terletak di folder satu tingkat ke bawah dari akar aplikasi Anda. Kedua, Anda memerlukan file JavaScript yang mengekspor fungsi Anda. Secara default, model mencari index.js file di folder yang sama dengan Anda function.json. Jika Anda menggunakan TypeScript, Anda harus menggunakan scriptFile properti untuk menunjuk ke file JavaScript yang dikompilasi function.json . Untuk mengkustomisasi lokasi file atau nama ekspor fungsi Anda, lihat mengonfigurasi titik masuk fungsi Anda.

Fungsi yang Anda ekspor harus selalu dideklarasikan sebagai async function dalam model v3. Anda dapat mengekspor fungsi sinkron, tetapi kemudian Anda harus memanggil untuk memberi context.done() sinyal bahwa fungsi Anda selesai, yang tidak digunakan lagi dan tidak disarankan.

Fungsi Anda diteruskan pemanggilan contextsebagai argumen pertama dan input Anda sebagai argumen yang tersisa.

Contoh berikut adalah fungsi sederhana yang mencatat bahwa fungsi tersebut dipicu dan merespons dengan Hello, world!:

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "authLevel": "anonymous",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}
module.exports = async function (context, request) {
    context.log('Http function was triggered.');
    context.res = { body: 'Hello, world!' };
};

Model pemrograman memuat fungsi Anda berdasarkan main bidang di Anda package.json. Anda dapat mengatur bidang ke main satu file atau beberapa file dengan menggunakan pola glob. Tabel berikut ini memperlihatkan contoh nilai untuk main bidang :

Contoh Deskripsi
src/index.js Mendaftarkan fungsi dari satu file akar.
src/functions/*.js Daftarkan setiap fungsi dari filenya sendiri.
src/{index.js,functions/*.js} Kombinasi tempat Anda mendaftarkan setiap fungsi dari filenya sendiri, tetapi Anda masih memiliki file root untuk kode tingkat aplikasi umum.

Untuk mendaftarkan fungsi, Anda harus mengimpor app objek dari @azure/functions modul npm dan memanggil metode khusus untuk jenis pemicu Anda. Argumen pertama saat mendaftarkan fungsi adalah nama fungsi. Argumen kedua adalah objek yang options menentukan konfigurasi untuk pemicu Anda, handler Anda, dan input atau output lainnya. Dalam beberapa kasus di mana konfigurasi pemicu tidak diperlukan, Anda dapat meneruskan handler secara langsung sebagai argumen kedua alih-alih options objek.

Mendaftarkan fungsi dapat dilakukan dari file apa pun dalam proyek Anda, selama file tersebut dimuat (secara langsung atau tidak langsung) berdasarkan main bidang dalam file Anda package.json . Fungsi harus didaftarkan pada cakupan global karena Anda tidak dapat mendaftarkan fungsi setelah eksekusi dimulai.

Contoh berikut adalah fungsi sederhana yang mencatat bahwa fungsi tersebut dipicu dan merespons dengan Hello, world!:

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

app.http('helloWorld1', {
    methods: ['POST', 'GET'],
    handler: async (request, context) => {
        context.log('Http function was triggered.');
        return { body: 'Hello, world!' };
    }
});

Input dan output

Fungsi Anda diperlukan untuk memiliki tepat satu input utama yang disebut pemicu. Ini mungkin juga memiliki input dan/atau output sekunder. Input dan output dikonfigurasi dalam file Anda function.json dan juga disebut sebagai pengikatan.

Input

Input adalah pengikatan dengan direction diatur ke in. Perbedaan utama antara pemicu dan input sekunder adalah bahwa type untuk pemicu berakhir di Trigger, misalnya jenis blobTrigger vs jenis blob. Sebagian besar fungsi hanya menggunakan pemicu, dan tidak banyak jenis input sekunder yang didukung.

Input dapat diakses dengan beberapa cara:

  • [Disarankan] Sebagai argumen yang diteruskan ke fungsi Anda: Gunakan argumen dalam urutan yang sama dengan yang ditentukan dalam function.json. Properti name yang ditentukan function.json dalam tidak perlu mencocokkan nama argumen Anda, meskipun disarankan demi organisasi.

    module.exports = async function (context, myTrigger, myInput, myOtherInput) { ... };
    
  • Sebagai properti context.bindings: Gunakan kunci yang cocok dengan properti yang name ditentukan dalam function.json.

    module.exports = async function (context) {
        context.log("This is myTrigger: " + context.bindings.myTrigger);
        context.log("This is myInput: " + context.bindings.myInput);
        context.log("This is myOtherInput: " + context.bindings.myOtherInput);
    };
    

Output

Output adalah pengikatan dengan direction diatur ke out dan dapat diatur dalam beberapa cara:

  • [Direkomendasikan untuk output tunggal] Mengembalikan nilai secara langsung: Jika Anda menggunakan fungsi asinkron, Anda dapat mengembalikan nilai secara langsung. Anda harus mengubah name properti pengikatan output menjadi $returnfunction.json seperti dalam contoh berikut:

    {
        "name": "$return",
        "type": "http",
        "direction": "out"
    }
    
    module.exports = async function (context, request) {
        return {
            body: "Hello, world!"
        };
    }
    
  • [Direkomendasikan untuk beberapa output] Mengembalikan objek yang berisi semua output: Jika Anda menggunakan fungsi asinkron, Anda dapat mengembalikan objek dengan properti yang cocok dengan nama setiap pengikatan di .function.json Contoh berikut menggunakan pengikatan output bernama "httpResponse" dan "queueOutput":

    {
        "name": "httpResponse",
        "type": "http",
        "direction": "out"
    },
    {
        "name": "queueOutput",
        "type": "queue",
        "direction": "out",
        "queueName": "helloworldqueue",
        "connection": "storage_APPSETTING"
    }
    
    module.exports = async function (context, request) {
        let message = 'Hello, world!';
        return {
            httpResponse: {
                body: message
            },
            queueOutput: message
        };
    };
    
  • Atur nilai pada context.bindings: Jika Anda tidak menggunakan fungsi asinkron atau Anda tidak ingin menggunakan opsi sebelumnya, Anda dapat mengatur nilai langsung pada , di context.bindingsmana kunci cocok dengan nama pengikatan. Contoh berikut menggunakan pengikatan output bernama "httpResponse" dan "queueOutput":

    {
        "name": "httpResponse",
        "type": "http",
        "direction": "out"
    },
    {
        "name": "queueOutput",
        "type": "queue",
        "direction": "out",
        "queueName": "helloworldqueue",
        "connection": "storage_APPSETTING"
    }
    
    module.exports = async function (context, request) {
        let message = 'Hello, world!';
        context.bindings.httpResponse = {
            body: message
        };
        context.bindings.queueOutput = message;
    };
    

Jenis data pengikatan

Anda dapat menggunakan dataType properti pada pengikatan input untuk mengubah jenis input Anda, namun memiliki beberapa batasan:

  • Dalam Node.js, hanya string dan binary didukung (stream tidak)
  • Untuk input HTTP, dataType properti diabaikan. Sebagai gantinya request , gunakan properti pada objek untuk mendapatkan isi dalam format yang Anda inginkan. Untuk informasi selengkapnya, lihat Permintaan HTTP.

Dalam contoh pemicu antrean penyimpanan berikut, jenis myQueueItem default adalah string, tetapi jika Anda mengatur dataType ke binary, jenis berubah menjadi Node.js Buffer.

{
    "name": "myQueueItem",
    "type": "queueTrigger",
    "direction": "in",
    "queueName": "helloworldqueue",
    "connection": "storage_APPSETTING",
    "dataType": "binary"
}
const { Buffer } = require('node:buffer');

module.exports = async function (context, myQueueItem) {
    if (typeof myQueueItem === 'string') {
        context.log('myQueueItem is a string');
    } else if (Buffer.isBuffer(myQueueItem)) {
        context.log('myQueueItem is a buffer');
    }
};

Fungsi Anda diperlukan untuk memiliki tepat satu input utama yang disebut pemicu. Ini mungkin juga memiliki input sekunder, output utama yang disebut output pengembalian, dan/atau output sekunder. Input dan output juga disebut sebagai pengikatan di luar konteks model pemrograman Node.js. Sebelum v4 model, pengikatan ini dikonfigurasi dalam function.json file.

Input pemicu

Pemicunya adalah satu-satunya input atau output yang diperlukan. Untuk sebagian besar jenis pemicu, Anda mendaftarkan fungsi dengan menggunakan metode pada objek bernama app sesuai jenis pemicu. Anda dapat menentukan konfigurasi khusus untuk pemicu langsung pada options argumen. Misalnya, pemicu HTTP memungkinkan Anda menentukan rute. Selama eksekusi, nilai yang sesuai dengan pemicu ini diteruskan sebagai argumen pertama ke handler Anda.

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

app.http('helloWorld1', {
    route: 'hello/world',
    handler: async (request, context) => {
        ...
    }
});

Menampilkan output

Output pengembalian bersifat opsional, dan dalam beberapa kasus dikonfigurasi secara default. Misalnya, pemicu HTTP yang terdaftar dikonfigurasi app.http untuk mengembalikan output respons HTTP secara otomatis. Untuk sebagian besar jenis output, Anda menentukan konfigurasi pengembalian pada options argumen dengan bantuan objek yang output diekspor dari @azure/functions modul. Selama eksekusi, Anda mengatur output ini dengan mengembalikannya dari handler Anda.

Contoh berikut menggunakan pemicu timer dan output antrean penyimpanan:

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

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: output.storageQueue({
        connection: 'storage_APPSETTING',
        ...
    }),
    handler: (myTimer, context) => {
        return { hello: 'world' }
    }
});

Input dan output tambahan

Selain pemicu dan pengembalian, Anda dapat menentukan input atau output tambahan pada options argumen saat mendaftarkan fungsi. Objek input dan output yang diekspor dari @azure/functions modul menyediakan metode khusus jenis untuk membantu membangun konfigurasi. Selama eksekusi, Anda mendapatkan atau mengatur nilai dengan context.extraInputs.get atau context.extraOutputs.set, meneruskan objek konfigurasi asli sebagai argumen pertama.

Contoh berikut adalah fungsi yang dipicu oleh antrean penyimpanan, dengan input blob penyimpanan tambahan yang disalin ke output blob penyimpanan tambahan. Pesan antrean harus menjadi nama file dan diganti {queueTrigger} sebagai nama blob yang akan disalin, dengan bantuan ekspresi pengikatan.

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

const blobInput = input.storageBlob({
    connection: 'storage_APPSETTING',
    path: 'helloworld/{queueTrigger}',
});

const blobOutput = output.storageBlob({
    connection: 'storage_APPSETTING',
    path: 'helloworld/{queueTrigger}-copy',
});

app.storageQueue('copyBlob1', {
    queueName: 'copyblobqueue',
    connection: 'storage_APPSETTING',
    extraInputs: [blobInput],
    extraOutputs: [blobOutput],
    handler: (queueItem, context) => {
        const blobInputValue = context.extraInputs.get(blobInput);
        context.extraOutputs.set(blobOutput, blobInputValue);
    }
});

Input dan output generik

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 ini generic juga dapat digunakan jika Anda ingin mengubah pengaturan default yang disediakan oleh metode khusus jenis.

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

Konteks pemanggilan

Setiap pemanggilan fungsi Anda melewati objek pemanggilan context , digunakan untuk membaca input, mengatur output, menulis ke log, dan membaca berbagai metadata. Dalam model v3, objek konteks selalu merupakan argumen pertama yang diteruskan ke handler Anda.

Objek context memiliki 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 nilai itu sendiri. Misalnya, pemicu pusat aktivitas 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 permintaan HTTP.
res Lihat respons HTTP.

context.executionContext

Objek context.executionContext memiliki properti berikut:

Properti Deskripsi
invocationId ID pemanggilan fungsi saat ini.
functionName Nama fungsi yang sedang dipanggil. Nama folder yang berisi function.json file menentukan nama fungsi.
functionDirectory Folder yang berisi function.json file.
retryContext Lihat konteks coba lagi.

context.executionContext.retryContext

Objek context.executionContext.retryContext memiliki properti berikut:

Properti Deskripsi
retryCount Angka yang menunjukkan upaya coba lagi saat ini.
maxRetryCount Jumlah maksimum kali eksekusi dicoba kembali. Nilai -1 berarti mencoba lagi tanpa batas.
exception Pengecualian yang menyebabkan coba lagi.

context.bindings

Objek context.bindings digunakan untuk membaca input atau mengatur output. Contoh berikut adalah pemicu antrean penyimpanan, yang menggunakan context.bindings untuk menyalin input blob penyimpanan ke output blob penyimpanan. Konten pesan antrean diganti sebagai {queueTrigger} 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;
};

context.done

Metode context.done ini tidak digunakan lagi. Sebelum fungsi asinkron didukung, Anda akan memberi sinyal fungsi Anda dilakukan dengan memanggil context.done():

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

Sekarang, disarankan untuk menghapus panggilan ke context.done() dan menandai fungsi Anda sebagai asinkron sehingga mengembalikan janji (bahkan jika Anda tidak await apa-apa). Segera setelah fungsi Anda selesai (dengan kata lain, janji yang dikembalikan diselesaikan), model v3 tahu fungsi Anda selesai.

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

Setiap pemanggilan fungsi Anda melewati objek pemanggilan context , dengan informasi tentang pemanggilan dan metode Anda yang digunakan untuk pengelogan. Dalam model v4, context objek biasanya merupakan argumen kedua yang diteruskan ke handler Anda.

Kelas InvocationContext memiliki 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 coba lagi.
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 pusat aktivitas memiliki enqueuedTimeUtc properti .
options Opsi yang digunakan saat mendaftarkan fungsi, setelah divalidasi dan dengan default yang ditentukan secara eksplisit.

Coba lagi konteks

Objek retryContext memiliki properti berikut:

Properti Deskripsi
retryCount Angka yang menunjukkan upaya coba lagi saat ini.
maxRetryCount Jumlah maksimum kali eksekusi dicoba kembali. Nilai -1 berarti mencoba lagi tanpa batas.
exception Pengecualian yang menyebabkan coba lagi.

Untuk informasi selengkapnya, lihat retry-policies .

Pencatatan

Di Azure Functions, disarankan untuk digunakan 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, rendering visual, dan analisis log aplikasi dan output jejak Anda. Untuk mempelajari selengkapnya, lihat memantau Azure Functions.

Catatan

Jika Anda menggunakan metode Node.js console.log alternatif, log tersebut dilacak di tingkat aplikasi dan tidak akan dikaitkan dengan fungsi tertentu. Sangat disarankan untuk digunakan context untuk pengelogan alih-alih console sehingga semua log dikaitkan dengan fungsi tertentu.

Contoh berikut menulis log pada tingkat "informasi" default, termasuk ID pemanggilan:

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

Tingkat log

Selain metode default context.log , metode berikut tersedia yang memungkinkan Anda menulis log pada tingkat tertentu:

Metode Deskripsi
context.log.error() Menulis peristiwa tingkat kesalahan ke 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 peristiwa tingkat kesalahan ke log.

Mengonfigurasi tingkat log

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

Melacak data kustom

Secara default, Azure Functions menulis output sebagai jejak ke Application Insights. Untuk kontrol lebih lanjut, Anda dapat menggunakan Application Insights Node.js SDK untuk mengirim data kustom ke instans Application Insights Anda.

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 menghubungkan semua log yang dihasilkan secara otomatis dan kustom 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 objek dan HttpResponse untuk mewakili pesan HTTP. Kelas mewakili subset standar pengambilan, menggunakan paket Node.js undici .

Permintaan HTTP

Permintaan dapat diakses 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 pengikatan input bernama: Opsi ini berfungsi sama dengan pengikatan non HTTP apa pun. 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. Disarankan untuk digunakan request.getHeader('header-name') sebagai gantinya, yang tidak peka huruf besar/kecil.
query Record<string, string> Kueri kunci parameter string dan nilai dari URL.
params Record<string, string> Merutekan kunci dan nilai parameter.
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 Isi sebagai string. Terlepas dari namanya, properti ini tidak mengembalikan Buffer.
bufferBody Buffer Tubuh sebagai penyangga.

Permintaan dapat diakses sebagai argumen pertama ke handler Anda untuk 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> Merutekan kunci dan nilai parameter.
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 Isi sebagai aliran yang dapat dibaca.
bodyUsed boolean Boolean yang menunjukkan apakah tubuh sudah dibaca.

Untuk mengakses isi permintaan atau respons, metode berikut dapat digunakan:

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

Catatan

Fungsi tubuh hanya dapat dijalankan sekali; Panggilan berikutnya akan diselesaikan dengan string kosong/ArrayBuffers.

Respons HTTP

Respons dapat diatur dalam beberapa cara:

  • 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 pengikatan output bernama: Opsi ini berfungsi sama dengan pengikatan non HTTP apa pun. 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. Ini secara implisit context.done() memanggil dan tidak dapat digunakan 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> (opsional) Header respons HTTP.
cookies Cookie[] (opsional) Cookie respons HTTP.
body any (opsional) Isi respons HTTP.
statusCode number (opsional) kode status respons HTTP. Jika tidak diatur, default ke 200.
status number (opsional) Sama seperti statusCode. Properti ini diabaikan jika statusCode diatur.

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

Metode Deskripsi
status() Mengatur status.
setHeader() Mengatur bidang header. CATATAN: res.set() dan res.header() juga didukung dan melakukan hal yang sama.
getHeader() Mendapatkan bidang header. CATATAN: res.get() juga didukung dan melakukan hal yang sama.
removeHeader() Menghapus header.
type() Mengatur header "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 melakukan hal yang 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.

Respons dapat diatur dalam beberapa cara:

  • Sebagai antarmuka sederhana dengan jenis HttpResponseInit: Opsi ini adalah cara yang paling ringkas untuk mengembalikan respons.

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

    Antarmuka HttpResponseInit memiliki properti berikut:

    Properti Tipe Deskripsi
    body BodyInit (opsional) Isi respons HTTP sebagai salah satu dari ArrayBuffer, , BlobAsyncIterable<Uint8Array>, FormData, Iterable<Uint8Array>, NodeJS.ArrayBufferView, URLSearchParams, null, atau string.
    jsonBody any (opsional) Isi Respons HTTP yang dapat diserialisasikan JSON. Jika diatur, HttpResponseInit.body properti diabaikan demi properti ini.
    status number (opsional) kode status respons HTTP. Jika tidak diatur, default ke 200.
    headers HeadersInit (opsional) Header respons HTTP.
    cookies Cookie[] (opsional) 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 Isi sebagai aliran yang dapat dibaca.
    bodyUsed boolean Boolean yang menunjukkan apakah tubuh telah dibaca dari sudah.

Aliran HTTP (pratinjau)

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.

Aliran HTTP saat ini dalam pratinjau.

Penting

Aliran HTTP tidak didukung dalam model v3. Tingkatkan ke model v4 untuk menggunakan fitur streaming HTTP.

Jenis dan HttpResponse yang ada HttpRequest dalam model pemrograman v4 sudah mendukung berbagai cara untuk menangani isi pesan, termasuk sebagai aliran.

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 FUNCTIONS_REQUEST_BODY_SIZE_LIMIT pengaturan di Azure. Ukuran isi maksimum default yang diizinkan adalah 104857600, yang membatasi permintaan Anda ke ukuran ~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 aliran

Contoh ini menunjukkan fungsi yang dipicu HTTP yang menerima data melalui permintaan HTTP POST, dan fungsi mengalirkan data ini ke file output tertentu:

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 ini menunjukkan fungsi yang dipicu HTTP yang mengalirkan konten file sebagai respons terhadap permintaan HTTP GET 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 };
    },
});

Pertimbangan streaming

  • Gunakan request.body untuk mendapatkan manfaat maksimum dari menggunakan aliran. Anda masih dapat terus menggunakan metode seperti request.text(), yang selalu mengembalikan isi sebagai string.

Hook

Hook tidak didukung dalam model v3. Tingkatkan ke model v4 untuk menggunakan kait.

Gunakan kait untuk menjalankan kode di titik yang berbeda dalam siklus hidup Azure Functions. Hook dijalankan dalam urutan terdaftar dan dapat didaftarkan dari file apa pun di aplikasi Anda. Saat ini ada dua cakupan kait, tingkat "aplikasi" dan tingkat "pemanggilan".

Kait pemanggilan

Kait pemanggilan dijalankan sekali per pemanggilan fungsi Anda, baik sebelum di preInvocation kait atau setelah di postInvocation kait. Secara default kait Anda dijalankan untuk semua jenis pemicu, tetapi Anda juga dapat memfilter berdasarkan jenis. Contoh berikut menunjukkan cara mendaftarkan kait pemanggilan dan memfilter berdasarkan jenis pemicu:

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

app.hook.preInvocation((context) => {
    if (context.invocationContext.options.trigger.type === 'httpTrigger') {
        context.invocationContext.log(
            `preInvocation hook executed for http function ${context.invocationContext.functionName}`
        );
    }
});

app.hook.postInvocation((context) => {
    if (context.invocationContext.options.trigger.type === 'httpTrigger') {
        context.invocationContext.log(
            `postInvocation hook executed for http function ${context.invocationContext.functionName}`
        );
    }
});

Argumen pertama untuk handler kait adalah objek konteks khusus untuk jenis kait tersebut.

Objek PreInvocationContext memiliki properti berikut:

Properti Deskripsi
inputs Argumen diteruskan ke pemanggilan.
functionHandler Handler fungsi untuk pemanggilan. Perubahan pada nilai ini memengaruhi fungsi itu sendiri.
invocationContext Objek konteks pemanggilan diteruskan ke fungsi .
hookData Tempat yang direkomendasikan untuk menyimpan dan berbagi data antara kait dalam cakupan yang sama. Anda harus menggunakan nama properti unik agar tidak berkonflik dengan data hook lain.

Objek PostInvocationContext memiliki properti berikut:

Properti Deskripsi
inputs Argumen diteruskan ke pemanggilan.
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 diteruskan ke fungsi .
hookData Tempat yang direkomendasikan untuk menyimpan dan berbagi data antara kait dalam cakupan yang sama. Anda harus menggunakan nama properti unik agar tidak berkonflik dengan data hook lain.

Kait aplikasi

Kait aplikasi dijalankan sekali per instans aplikasi Anda, baik selama startup di appStart hook atau selama penghentian di appTerminate hook. Kait penghentian aplikasi memiliki waktu terbatas untuk dijalankan dan tidak dijalankan dalam semua skenario.

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

Contoh berikut mendaftarkan kait aplikasi:

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

app.hook.appStart((context) => {
    // add your logic here
});

app.hook.appTerminate((context) => {
    // add your logic here
});

Argumen pertama untuk handler kait adalah objek konteks khusus untuk jenis kait tersebut.

Objek AppStartContext memiliki properti berikut:

Properti Deskripsi
hookData Tempat yang direkomendasikan untuk menyimpan dan berbagi data antara kait dalam cakupan yang sama. Anda harus menggunakan nama properti unik agar tidak berkonflik dengan data hook lain.

Objek AppTerminateContext memiliki properti berikut:

Properti Deskripsi
hookData Tempat yang direkomendasikan untuk menyimpan dan berbagi data antara kait dalam cakupan yang sama. Anda harus menggunakan nama properti unik agar tidak berkonflik dengan data hook lain.

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 jenis pemicu untuk memutuskan kapan harus menambahkan instans, 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 terikat CPU, Anda dapat meningkatkan performa lebih lanjut dengan menggunakan beberapa proses pekerja 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 permintaan fungsi simultan secara merata ke seluruh pekerja. Perilaku ini membuatnya lebih kecil kemungkinan fungsi intensif CPU memblokir fungsi lain agar tidak berjalan. Pengaturan ini berlaku untuk setiap host yang dibuat Azure Functions 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, sangat disarankan untuk mengimbangi kelemahan ini dengan menjalankan dari file paket.

Versi node

Anda dapat melihat versi saat ini yang digunakan runtime dengan mencatat process.version dari fungsi apa 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, versi Node.js diatur oleh WEBSITE_NODE_DEFAULT_VERSION pengaturan aplikasi. Pengaturan ini dapat diperbarui baik dengan menggunakan Azure CLI atau di portal Azure.

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

Sebelum memutakhirkan versi Node.js Anda, pastikan aplikasi fungsi Anda berjalan pada versi terbaru runtime Azure Functions. Jika Anda perlu meningkatkan versi runtime Anda, lihat Memigrasikan 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=~20 \
 --name <FUNCTION_APP_NAME> --resource-group <RESOURCE_GROUP_NAME> 

Ini mengatur WEBSITE_NODE_DEFAULT_VERSION pengaturan aplikasi versi LTS yang didukung dari ~20.

Setelah perubahan dilakukan, aplikasi fungsi Anda dimulai ulang. Untuk mempelajari selengkapnya tentang dukungan Functions untuk Node.js, lihat Kebijakan dukungan runtime bahasa.

Variabel lingkungan

Variabel lingkungan dapat berguna untuk rahasia operasional (string koneksi, kunci, titik akhir, dll.) atau pengaturan lingkungan seperti variabel pembuatan profil. Anda dapat menambahkan variabel lingkungan di lingkungan lokal dan cloud Anda dan mengaksesnya dalam 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

Ada beberapa variabel lingkungan Functions khusus untuk Node.js:

languageWorkers__node__arguments

Pengaturan ini memungkinkan Anda menentukan argumen kustom saat memulai proses Node.js Anda. Ini paling sering digunakan secara lokal untuk memulai pekerja dalam mode debug, tetapi juga dapat digunakan di Azure jika Anda memerlukan argumen kustom.

Peringatan

Jika memungkinkan, hindari penggunaan languageWorkers__node__arguments di Azure karena dapat memiliki efek negatif pada waktu mulai dingin. Daripada menggunakan pekerja yang telah dihangatkan sebelumnya, runtime harus memulai pekerja baru dari awal dengan argumen kustom Anda.

logging__logLevel__Worker

Pengaturan ini menyesuaikan tingkat log default untuk log pekerja khusus 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

Karena modul ECMAScript saat ini adalah 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 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

Properti function.jsonscriptFile dan entryPoint dapat digunakan untuk mengonfigurasi lokasi dan nama fungsi yang diekspor. Properti scriptFile diperlukan saat Anda menggunakan TypeScript dan harus menunjuk ke JavaScript yang dikompilasi.

Menggunakan scriptFile

Fungsi JavaScript dijalankan secara default dari index.js–file yang berbagi direktori induk yang sama dengan direktori yang sesuai function.json.

scriptFile dapat digunakan untuk mendapatkan struktur folder yang terlihat seperti contoh berikut:

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

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

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

Menggunakan entryPoint

Dalam model v3, fungsi harus diekspor menggunakan module.exports agar dapat ditemukan dan dijalankan. Secara default, fungsi yang dijalankan ketika dipicu adalah satu-satunya ekspor dari file itu, ekspor bernama run, atau ekspor bernama index. Contoh berikut diatur entryPointfunction.json ke nilai kustom, "logHello":

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

module.exports = { logHello };

Penelusuran kesalahan lokal

Disarankan untuk menggunakan Visual Studio Code untuk penelusuran kesalahan lokal, yang memulai proses Node.js Anda dalam mode debug secara otomatis dan melampirkan ke proses untuk Anda. Untuk informasi selengkapnya, lihat menjalankan fungsi secara lokal.

Jika Anda menggunakan alat lain untuk penelusuran kesalahan atau ingin memulai proses Node.js dalam mode debug secara manual, tambahkan "languageWorkers__node__arguments": "--inspect" di bawah Values di local.settings.json Anda. Argumen --inspect memberi tahu Node.js untuk mendengarkan klien debug, pada port 9229 secara default. Untuk informasi selengkapnya, lihat panduan penelusuran kesalahan Node.js.

Rekomendasi

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

Memilih paket App Service vCPU tunggal

Saat Anda membuat aplikasi fungsi yang menggunakan paket App Service, kami sarankan Anda memilih paket vCPU tunggal daripada paket dengan banyak vCPU. Saat ini, Functions menjalankan fungsi Node.js lebih efisien pada VM vCPU tunggal, dan menggunakan VM yang lebih besar tidak menghasilkan peningkatan performa yang diharapkan. Jika perlu, Anda dapat memperluas skala secara manual dengan menambahkan lebih banyak instans VM dengan vCPU tunggal, atau Anda dapat mengaktifkan autoscale. Untuk informasi selengkapnya, lihat Skalakan jumlah instans secara manual atau otomatis.

Jalankan dari file paket

Saat Anda mengembangkan Azure Functions dalam model hosting tanpa server, cold start adalah 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 besar khususnya, cold start bisa signifikan. Untuk mempercepat proses cold start, jalankan fungsi Anda sebagai file paket jika memungkinkan. Banyak metode penyebaran menggunakan model ini secara default, tetapi jika Anda mengalami cold start besar, Anda harus memeriksa untuk memastikan Anda menjalankan dengan cara ini.

Menggunakan satu klien statis

Saat Anda menggunakan klien khusus layanan di aplikasi Azure Functions, jangan membuat klien baru dengan setiap pemanggilan fungsi karena Anda dapat mencapai batas koneksi. Sebagai gantinya, buat klien statis tunggal di lingkup global. Untuk informasi selengkapnya, lihat mengelola koneksi di Azure Functions.

Gunakan async dan await

Saat menulis Azure Functions di Node.js, Anda harus menulis kode menggunakan async kata kunci dan await . Menulis kode menggunakan async dan await alih-alih panggilan balik atau .then dan .catch dengan Promises membantu menghindari dua masalah umum:

  • Melemparkan pengecualian tak tertangkap yang menabrak proses Node.js, yang berpotensi memengaruhi eksekusi fungsi lain.
  • Perilaku tak terduga, seperti log yang hilang dari context.log, yang disebabkan oleh panggilan asinkron yang tidak ditunggu 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 tertangkap dalam cakupan yang benar dapat merusak seluruh proses (masalah #1). Mengembalikan tanpa memastikan panggilan balik selesai berarti respons http terkadang akan 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 disebutkan sebelumnya. Pengecualian yang tidak secara eksplisit tertangkap dalam cakupan yang benar dapat merusak seluruh proses (masalah #1). Memanggil metode yang tidak digunakan context.done() lagi di luar cakupan panggilan balik dapat memberi sinyal 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();
}

async Gunakan kata kunci dan await untuk membantu menghindari kedua masalah ini. Sebagian besar API dalam ekosistem Node.js telah dikonversi untuk mendukung janji dalam beberapa bentuk. Misalnya, mulai dari v14, Node.js menyediakan fs/promises API untuk mengganti api fs panggilan balik.

Dalam contoh berikut, setiap pengecualian yang tidak tertangani yang dilemparkan selama eksekusi fungsi hanya gagal 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;
        }
    },
});

Dengan async dan await, Anda juga tidak perlu melakukan panggilan balik 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: