Share via


ontwikkelaarshandleiding voor Azure Functions Node.js

Deze handleiding is een inleiding tot het ontwikkelen van Azure Functions met behulp van JavaScript of TypeScript. In het artikel wordt ervan uitgegaan dat u de Azure Functions ontwikkelaarshandleiding al hebt gelezen.

Belangrijk

De inhoud van dit artikel wordt gewijzigd op basis van uw keuze uit het Node.js programmeermodel in de selector boven aan deze pagina. De versie die u kiest, moet overeenkomen met de versie van het npm-pakket dat u in uw app gebruikt. Als u dat pakket niet in uw lijst hebt, is de standaardwaarde v3. Meer informatie over de verschillen tussen v3 en v4 in de migratiehandleiding.

Als Node.js ontwikkelaar bent u mogelijk ook geïnteresseerd in een van de volgende artikelen:

Aan de slag Concepten Gestuurd leren
  • Ontwikkelaarshandleiding
  • Hostingopties
  • Prestatieoverwegingen
  • Serverloze toepassingen maken
  • Node.js en Express-API's herstructureren naar serverloze API's

Overwegingen

  • Het Node.js programmeermodel mag niet worden verward met de Azure Functions runtime:
    • Programmeermodel: Definieert hoe u uw code ontwerpt en specifiek is voor JavaScript en TypeScript.
    • Runtime: definieert het onderliggende gedrag van Azure Functions en wordt gedeeld in alle talen.
  • De versie van het programmeermodel is strikt gekoppeld aan de versie van het npm-pakket. Deze versie wordt onafhankelijk van de runtime geversied. Zowel de runtime als het programmeermodel gebruiken het nummer 4 als hun laatste hoofdversie, maar dat is toeval.
  • U kunt de v3- en v4-programmeermodellen niet combineren in dezelfde functie-app. Zodra u één v4-functie in uw app registreert, worden alle v3-functies die zijn geregistreerd in function.json bestanden genegeerd.

Ondersteunde versies

In de volgende tabel ziet u elke versie van het Node.js programmeermodel, samen met de ondersteunde versies van de Azure Functions runtime en Node.js.

Versie van programmeermodel Ondersteuningsniveau Runtimeversie van Functions Node.js versie Beschrijving
4.x Algemene Vergadering 4.25+ 22.x 20.x, 18.x Ondersteunt een flexibele bestandsstructuur en codegerichte benadering voor triggers en bindingen.
3.x Algemene Vergadering 4.x 20.x, 18.x, 16.x, 14.x Vereist een specifieke bestandsstructuur met uw triggers en bindingen die zijn gedeclareerd in een 'function.json'-bestand
2.x n.v.t. 3.x 14.x, 12.x, 10.x Bereikt einde van de ondersteuning op 13 december 2022. Zie Functions-versies voor meer informatie.
1.x n.v.t. 2.x 10.x, 8.x Bereikt einde van de ondersteuning op 13 december 2022. Zie Functions-versies voor meer informatie.

Mapstructuur

  • JavaScript
  • TypeScript

De vereiste mapstructuur voor een JavaScript-project ziet eruit als in het volgende voorbeeld:

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

De hoofdprojectmap, project_root, kan de volgende bestanden bevatten:

  • .vscode/: (optioneel) Bevat de opgeslagen Visual Studio Code-configuratie. Zie Visual Studio Code settings voor meer informatie.
  • myFirstFunction/function.json: bevat configuratie voor de trigger, invoer en uitvoer van de functie. De naam van de map bepaalt de naam van uw functie.
  • myFirstFunction/index.js: Slaat uw functiecode op. Zie door scriptFile te gebruiken om dit standaardbestandspad te wijzigen.
  • .funcignore: (Optioneel) Declareert bestanden die niet mogen worden gepubliceerd naar Azure. Meestal bevat dit bestand .vscode/ om uw editorinstelling te negeren, test/ testcases te negeren en local.settings.json om te voorkomen dat lokale app-instellingen worden gepubliceerd.
  • host.json: bevat configuratieopties die van invloed zijn op alle functies in een exemplaar van een functie-app. Dit bestand wordt gepubliceerd naar Azure. Niet alle opties worden ondersteund bij lokaal uitvoeren. Zie host.json voor meer informatie.
  • local.settings.json: wordt gebruikt voor het opslaan van app-instellingen en verbindingsreeks s wanneer deze lokaal wordt uitgevoerd. Dit bestand wordt niet gepubliceerd naar Azure. Zie local.settings.file voor meer informatie.
  • package.json: bevat configuratieopties zoals een lijst met pakketafhankelijkheden, het hoofdinvoerpunt en scripts.
  • JavaScript
  • TypeScript

De aanbevolen mapstructuur voor een JavaScript-project ziet er als volgt uit:

<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

De hoofdprojectmap, project_root, kan de volgende bestanden bevatten:

  • .vscode/: (optioneel) Bevat de opgeslagen Visual Studio Code-configuratie. Zie Visual Studio Code settings voor meer informatie.
  • src/functions/: de standaardlocatie voor alle functies en de bijbehorende triggers en bindingen.
  • test/: (optioneel) Bevat de testcases van uw functie-app.
  • .funcignore: (Optioneel) Declareert bestanden die niet mogen worden gepubliceerd naar Azure. Meestal bevat dit bestand .vscode/ om uw editorinstelling te negeren, test/ testcases te negeren en local.settings.json om te voorkomen dat lokale app-instellingen worden gepubliceerd.
  • host.json: bevat configuratieopties die van invloed zijn op alle functies in een exemplaar van een functie-app. Dit bestand wordt gepubliceerd naar Azure. Niet alle opties worden ondersteund bij lokaal uitvoeren. Zie host.json voor meer informatie.
  • local.settings.json: wordt gebruikt voor het opslaan van app-instellingen en verbindingsreeks s wanneer deze lokaal wordt uitgevoerd. Dit bestand wordt niet gepubliceerd naar Azure. Zie local.settings.file voor meer informatie.
  • package.json: bevat configuratieopties zoals een lijst met pakketafhankelijkheden, het hoofdinvoerpunt en scripts.

Een functie registreren

Het v3-model registreert een functie op basis van het bestaan van twee bestanden. Eerst hebt u een bestand in een map nodig die zich één niveau lager bevindt dan de hoofdmap van uw app. Ten tweede hebt u een JavaScript-bestand nodig dat uw functie exporteert . Standaard zoekt het model naar een bestand in dezelfde map als uw . Als u TypeScript gebruikt, moet u de eigenschap gebruiken om naar het gecompileerde JavaScript-bestand te verwijzen. Als u de bestandslocatie of exportnaam van uw functie wilt aanpassen, raadpleegt u het configureren van het toegangspunt van uw functie.

De functie die u exporteert, moet altijd worden gedeclareerd als een in het v3-model. U kunt een synchrone functie exporteren, maar vervolgens moet u aanroepen om aan te geven dat uw functie is voltooid, wat is afgeschaft en niet wordt aanbevolen.

Uw functie wordt met een invocation als het eerste argument en uw invoer als de overige argumenten meegenomen.

Het volgende voorbeeld is een eenvoudige functie waarmee wordt geregistreerd dat deze is geactiveerd en reageert met :

  • JavaScript
  • TypeScript
{
  "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!" };
};

Het programmeermodel laadt uw functies op basis van het veld in uw . U kunt het veld instellen op één bestand of meerdere bestanden met behulp van een glob-patroon. In de volgende tabel ziet u voorbeeldwaarden voor het veld:

  • JavaScript
  • TypeScript
Voorbeeld Beschrijving
src/index.js Registreer functies uit één hoofdbestand.
src/functions/*.js Registreer elke functie uit een eigen bestand.
src/{index.js,functions/*.js} Een combinatie waarbij u elke functie registreert vanuit een eigen bestand, maar u hebt nog steeds een hoofdbestand voor algemene code op app-niveau.

Als u een functie wilt registreren, moet u het object importeren uit de npm-module en de methode aanroepen die specifiek is voor uw triggertype. Het eerste argument bij het registreren van een functie is de functienaam. Het tweede argument is een object dat de configuratie voor uw trigger, uw handler en andere invoer of uitvoer aangeeft. In sommige gevallen waarin triggerconfiguratie niet nodig is, kunt u de handler rechtstreeks doorgeven als het tweede argument in plaats van een object.

Het registreren van een functie kan worden uitgevoerd vanuit elk bestand in uw project, zolang dat bestand (direct of indirect) wordt geladen op basis van het veld in uw bestand. De functie moet worden geregistreerd in een globaal bereik, omdat u functies niet kunt registreren zodra de uitvoeringen zijn gestart.

Het volgende voorbeeld is een eenvoudige functie waarmee wordt geregistreerd dat deze is geactiveerd en reageert met :

  • JavaScript
  • TypeScript
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!" };
  },
});

Invoer en uitvoer

Uw functie moet precies één primaire invoer trigger genaamd hebben. Het kan ook secundaire invoer en/of uitvoer hebben. Invoer en uitvoer worden geconfigureerd in uw bestanden en worden ook wel bindingen genoemd.

Invoer

Invoer zijn bindingen die zijn ingesteld op . Het belangrijkste verschil tussen een trigger en een secundaire invoer is dat de voor een trigger eindigt in , bijvoorbeeld type versus type . De meeste functies gebruiken alleen een trigger en er worden niet veel secundaire invoertypen ondersteund.

Invoer kan op verschillende manieren worden geopend:

  • [Aanbevolen] Als argumenten die worden doorgegeven aan uw functie: gebruik de argumenten in dezelfde volgorde waarin ze zijn gedefinieerd . De -eigenschap die in is gedefinieerd hoeft niet overeen te komen met de naam van uw argument, hoewel we het voor de organisatie aanbevelen.

    • JavaScript
    • TypeScript
    module.exports = async function (context, myTrigger, myInput, myOtherInput) { ... };
    

  • Als eigenschappen van : Gebruik de sleutel die overeenkomt met de eigenschap die is gedefinieerd in .

    • JavaScript
    • TypeScript
    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);
    };
    

Uitgangen

Op verschillende manieren kunnen uitvoerbindingen worden geconfigureerd met ingesteld op .

  • [Aanbevolen voor één uitvoer] Retourneer de waarde rechtstreeks: Als u een asynchrone functie gebruikt, kunt u de waarde rechtstreeks retourneren. U moet de -eigenschap van de uitvoerbinding wijzigen naar in , zoals in het volgende voorbeeld.

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

  • [Aanbevolen voor meerdere uitvoerbewerkingen] Retourneert een object met alle uitvoerwaarden: als u een asynchrone functie gebruikt, kunt u een object retourneren met een eigenschap die overeenkomt met de naam van elke binding in uw . In het volgende voorbeeld worden uitvoerbindingen met de naam httpResponse en queueOutput gebruikt:

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

  • Stel waarden in op : Als u geen asynchrone functie gebruikt of u de vorige opties niet wilt gebruiken, kunt u waarden rechtstreeks instellen, waarbij de sleutel overeenkomt met de naam van de binding. In het volgende voorbeeld worden uitvoerbindingen met de naam httpResponse en queueOutput gebruikt:

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

Gegevenstype Bindingen

U kunt de eigenschap op een invoerbinding gebruiken om het type invoer te wijzigen. De aanpak heeft echter enkele beperkingen:

  • Alleen in Node.js en worden ondersteund ( niet)
  • Voor HTTP-invoer wordt de eigenschap genegeerd. Gebruik in plaats daarvan eigenschappen voor het object om de hoofdtekst in de gewenste indeling op te halen. Zie HTTP-aanvraag voor meer informatie.

In het volgende voorbeeld van een opslagwachtrij-trigger, het standaardtype van is een , maar als u instelt op , verandert het type naar een Node.js .

{
  "name": "myQueueItem",
  "type": "queueTrigger",
  "direction": "in",
  "queueName": "helloworldqueue",
  "connection": "storage_APPSETTING",
  "dataType": "binary"
}
  • JavaScript
  • TypeScript
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");
  }
};

Uw functie moet precies één primaire invoer trigger genaamd hebben. Het kan ook secundaire invoer hebben, een primaire uitvoer genaamd de retouruitvoer en/of secundaire uitvoer. Invoer en uitvoer worden ook wel bindingen genoemd buiten de context van het Node.js programmeermodel. Vóór v4 van het model zijn deze bindingen geconfigureerd in bestanden.

Trigger-invoer

De trigger is de enige vereiste invoer of uitvoer. Voor de meeste triggertypen registreert u een functie met behulp van een methode in het object met de naam van het triggertype. U kunt configuratie opgeven die specifiek is voor de trigger rechtstreeks op het argument. Met een HTTP-trigger kunt u bijvoorbeeld een route opgeven. Tijdens de uitvoering wordt de waarde die overeenkomt met deze trigger doorgegeven als het eerste argument aan uw handler.

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

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

Uitvoer retourneren

De retouruitvoer is optioneel en in sommige gevallen standaard geconfigureerd. Een HTTP-trigger die is geregistreerd met , is bijvoorbeeld geconfigureerd om automatisch een HTTP-antwoord te retourneren. Voor de meeste uitvoertypen geeft u de retourconfiguratie voor het argument op met behulp van het object dat uit de module is geëxporteerd. Tijdens de uitvoering stelt u deze uitvoer in door deze vanuit uw handler te retourneren.

In het volgende voorbeeld wordt een timertrigger en uitvoer van een opslagwachtrij gebruikt:

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

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

Extra invoer en uitvoer

Naast de trigger en retour kunt u extra invoer of uitvoer opgeven voor het argument bij het registreren van een functie. De en objecten die uit de module worden geëxporteerd, bieden typespecifieke methoden om de configuratie samen te stellen. Tijdens de uitvoering krijgt of stelt u de waarden in met of , waarbij u het oorspronkelijke configuratieobject doorgeeft als het eerste argument.

Het volgende voorbeeld is een functie die wordt geactiveerd door een opslagwachtrij, met een extra opslagblobinvoer die wordt gekopieerd naar een extra opslagblobuitvoer. Het wachtrijbericht moet de naam van een bestand zijn en vervangt als de blobnaam die moet worden gekopieerd, met behulp van een bindingexpressie.

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

Algemene invoer en uitvoer

De , en objecten die door de module worden geëxporteerd, bieden typespecifieke methoden voor de meeste typen. Voor alle typen die niet worden ondersteund, wordt een methode opgegeven waarmee u de configuratie handmatig kunt opgeven. De methode kan ook worden gebruikt als u de standaardinstellingen van een typespecifieke methode wilt wijzigen.

Het volgende voorbeeld is een eenvoudige door HTTP geactiveerde functie met behulp van algemene methoden in plaats van typespecifieke methoden.

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

SDK-typen

Met verschillende bindingsextensies kunt u nu rechtstreeks met de Azure SDK typen werken.

Azure Blob Storage

Met sdk-bindingen in Azure Functions kunt u rechtstreeks werken met de Azure Blob Storage SDK-typen, zoals BlobClient en ContainerClient in plaats van onbewerkte gegevens. Dit biedt volledige toegang tot alle SDK-methoden bij het werken met blobs.

Uw project configureren voor gebruik met SDK-typen:

  1. Voeg de preview-pakketten van de extensie toe aan het bestand in het project, die ten minste de volgende pakketten moeten bevatten:
"dependencies": {
  "@azure/functions": "4.7.2-preview",
  "@azure/functions-extensions-blob": "0.2.0-preview"
},
  1. Voeg uw toe om streamingtypen te ondersteunen:
import { app } from '@azure/functions';

app.setup({
    enableHttpStream: true,
});

In dit voorbeeld ziet u hoe u de BlobClient kunt ophalen van zowel een Storage Blob-trigger als van de invoerbinding op een HTTP-trigger:

import "@azure/functions-extensions-blob"; // This is the mandatory first import for SDK binding
import { StorageBlobClient } from "@azure/functions-extensions-blob";
import { app, InvocationContext } from "@azure/functions";

export async function storageBlobTrigger(
  blobStorageClient: StorageBlobClient, // SDK binding provides this client
  context: InvocationContext
): Promise<void> {
  context.log(`Blob trigger processing: ${context.triggerMetadata.name}`);

  // Access to full SDK capabilities
  const blobProperties = await blobStorageClient.blobClient.getProperties();
  context.log(`Blob size: ${blobProperties.contentLength}`);

  // Download blob content
  const downloadResponse = await blobStorageClient.blobClient.download();
  context.log(`Content: ${downloadResponse}`);
}

// Register the function
app.storageBlob("storageBlobTrigger", {
  path: "snippets/{name}",
  connection: "AzureWebJobsStorage",
  sdkBinding: true, // Enable SDK binding
  handler: storageBlobTrigger,
});

In dit voorbeeld ziet u hoe u de invoerbinding voor opslagblob kunt ophalen met behulp van een HTTP-trigger:

import "@azure/functions-extensions-blob"; // This is the mandatory first import for SDK binding
import { StorageBlobClient } from "@azure/functions-extensions-blob";
import {
  app,
  HttpRequest,
  HttpResponseInit,
  input,
  InvocationContext,
} from "@azure/functions";

const blobInput = input.storageBlob({
  path: "snippets",
  connection: "AzureWebJobsStorage",
  sdkBinding: true,
});

export async function listBlobs(
  request: HttpRequest,
  context: InvocationContext
): Promise<HttpResponseInit> {
  // Get input binding for a specific container
  const storageBlobClient = context.extraInputs.get(
    blobInput
  ) as StorageBlobClient;

  // List all blobs in the container
  const blobs = [];
  for await (const blob of storageBlobClient.containerClient.listBlobsFlat()) {
    blobs.push(blob.name);
  }

  return { jsonBody: { blobs } };
}

app.http("listBlobs", {
  methods: ["GET"],
  authLevel: "function",
  extraInputs: [blobInput],
  handler: listBlobs,
});

Houd rekening met deze overwegingen bij het werken met SDK-typen:

  • Zorg ervoor dat altijd eerst in uw bestanden staat om ervoor te zorgen dat eventuele bijwerkingen worden uitgevoerd.
  • Stel in in uw bindingsconfiguratie.
  • Gebruik het juiste clienttype voor uw bewerking:
    • voor bewerkingen op één blob
    • voor bewerkingen in een container
  • Fouten op de juiste wijze verwerken met blokken
  • Voor grote blobbewerkingen kunt u streamingmethoden gebruiken om geheugenproblemen te voorkomen.

Zie deze Blob Storage SDK-bindingen voor Node.js voorbeelden voor meer informatie: voor meer voorbeelden over het opnemen van SDK-bindingen voor Blob in uw functie-app.

Azure Service Bus

In dit voorbeeld wordt het SDK-type ServiceBusReceivedMessage opgehaald uit ServiceBusMessageContext die wordt geleverd door de Service Bus-trigger:

import '@azure/functions-extensions-servicebus'; // Ensure the Service Bus extension is imported
import { app, InvocationContext } from '@azure/functions';
import { ServiceBusMessageContext } from '@azure/functions-extensions-servicebus';
import { parseBody } from '../servicebus-helpers'; // Interim helper until #50 lands

// This sample uses sdkBinding = true with manual message completion.
// With v0.4.0, message.body is returned as a raw Buffer instead of auto-parsed object.
export async function serviceBusQueueTrigger(
    serviceBusMessageContext: ServiceBusMessageContext,
    context: InvocationContext
): Promise<void> {
    const message = serviceBusMessageContext.messages[0];

    // v0.4.0: message.body is a Buffer — use parseBody<T>() helper for one-line parsing
    const bodyData = parseBody(message);
    context.log('Parsed message body:', bodyData);

    // Get current retry count from custom properties, default to 0
    const currentRetryCount = message.applicationProperties?.retryCnt
        ? parseInt(message.applicationProperties.retryCnt as string)
        : 0;
    context.log(`Current retry count: ${currentRetryCount}`);

    if (currentRetryCount >= 3) {
        // After 3 retries, complete the message to remove it from the queue
        context.log(`Maximum retry count (3) reached. Completing message to prevent infinite loop.`);
        await serviceBusMessageContext.actions.complete(message);
        context.log('Message completed after maximum retries');
    } else {
        // Abandon with updated retry count
        const newRetryCount = currentRetryCount + 1;
        const propertiesToModify = {
            retryCnt: newRetryCount.toString(),
            lastRetryTime: new Date().toISOString(),
            errorMessage: 'Processing failed',
        };

        context.log(`Abandoning message with retry count: ${newRetryCount}`);
        await serviceBusMessageContext.actions.abandon(message, propertiesToModify);
    }

    context.log('triggerMetadata: ', context.triggerMetadata);
}

app.serviceBusQueue('serviceBusQueueTrigger1', {
    connection: 'ServiceBusConnection',
    queueName: 'testqueue',

Zie het exponential backoff-strategievoorbeeld voor een ander voorbeeld van SDK-typen.

Aanroepcontext

Elke aanroep van uw functie wordt doorgegeven aan een aanroepobject , gebruikt voor het lezen van invoer, het instellen van uitvoer, schrijven naar logboeken en het lezen van verschillende metagegevens. In het v3-model is het contextobject altijd het eerste argument dat aan uw handler wordt doorgegeven.

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
invocationId De ID van de huidige functieaanroep.
executionContext Bekijk de uitvoeringscontext.
bindings Zie bindingen.
bindingData Metagegevens over de triggerinvoer voor deze aanroep, niet inclusief de waarde zelf. Een Event Hub-trigger heeft bijvoorbeeld een eigenschap.
traceContext De context voor gedistribueerde tracering. Zie voor meer informatie.
bindingDefinitions De configuratie van uw invoer en uitvoer, zoals gedefinieerd in .
req Zie http-aanvraag.
res Zie http-antwoord.

context.executionContext

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
invocationId De ID van de huidige functieaanroep.
functionName De naam van de functie die wordt aangeroepen. De naam van de map met het bestand bepaalt de naam van de functie.
functionDirectory De map met het bestand.
retryContext Zie herhalingscontext.

context.executionContext.retryContext

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
retryCount Een getal dat de huidige poging voor opnieuw proberen aangeeft.
maxRetryCount Maximum aantal keren dat een uitvoering opnieuw wordt geprobeerd. Een waarde van betekent om het voor onbepaalde tijd opnieuw te proberen.
exception Uitzondering die de nieuwe poging heeft veroorzaakt.

context.bindingen

Het object wordt gebruikt om invoer te lezen of uitvoer in te stellen. Het volgende voorbeeld is een opslagwachtrijtrigger, die gebruikt om een opslagblobinvoer te kopiëren naar een opslagblobuitvoer. De inhoud van het wachtrijbericht vervangt als de bestandsnaam om te kopiëren, met behulp van een bindingsexpressie.

{
    "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"
}
  • JavaScript
  • TypeScript
module.exports = async function (context, myQueueItem) {
  const blobValue = context.bindings.myInput;
  context.bindings.myOutput = blobValue;
};

context.afgesloten

De methode is afgeschaft. Voordat asynchrone functies werden ondersteund, zou u aangeven dat uw functie wordt uitgevoerd door het aanroepen van:

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

We raden aan om de aanroep van te verwijderen en uw functie als asynchroon te markeren zodat deze een Promise retourneert (zelfs als u niets met doet). Zodra uw functie is voltooid (met andere woorden, de geretourneerde belofte wordt afgehandeld), weet het v3-model dat uw functie is afgerond.

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

Elke aanroep van uw functie wordt doorgegeven aan een aanroepobject , met informatie over uw aanroep en methoden die worden gebruikt voor logboekregistratie. In het v4-model is het object doorgaans het tweede argument dat wordt doorgegeven aan uw handler.

De klasse heeft de volgende eigenschappen:

Eigenschap Beschrijving
invocationId De ID van de huidige functieaanroep.
functionName De naam van de functie.
extraInputs Wordt gebruikt om de waarden van extra invoer op te halen. Zie extra invoer en uitvoer voor meer informatie.
extraOutputs Wordt gebruikt om de waarden van extra uitvoer in te stellen. Zie extra invoer en uitvoer voor meer informatie.
retryContext Zie herhalingscontext.
traceContext De context voor gedistribueerde tracering. Zie voor meer informatie.
triggerMetadata Metagegevens over de triggerinvoer voor deze aanroep, niet inclusief de waarde zelf. Een Event Hub-trigger heeft bijvoorbeeld een eigenschap.
options De opties die worden gebruikt bij het registreren van de functie, nadat ze zijn gevalideerd en met standaardinstellingen expliciet zijn opgegeven.

Opnieuw probeercontext

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
retryCount Een getal dat de huidige poging voor opnieuw proberen aangeeft.
maxRetryCount Maximum aantal keren dat een uitvoering opnieuw wordt geprobeerd. Een waarde van betekent om het voor onbepaalde tijd opnieuw te proberen.
exception Uitzondering die de nieuwe poging heeft veroorzaakt.

Zie voor meer informatie.

Logboekregistratie

In Azure Functions is het raadzaam om context.log() te gebruiken om logboeken te schrijven. Azure Functions integreert met Azure-toepassing Insights om uw functie-app-logboeken beter vast te leggen. Application Insights, onderdeel van Azure Monitor, biedt faciliteiten voor verzameling, visuele rendering en analyse van zowel toepassingslogboeken als traceringsuitvoer. Zie monitoring Azure Functions voor meer informatie.

Notitie

Als u de alternatieve methode Node.js gebruikt, worden deze logboeken bijgehouden op app-niveau en worden deze niet gekoppeld aan een specifieke functie. Wij raden u sterk aan om te gebruiken voor het loggen in plaats van , zodat alle logboeken aan een specifieke functie zijn gekoppeld.

In het volgende voorbeeld wordt een logboek op het standaardniveau 'informatie' geschreven, inclusief de aanroep-id:

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

Logboekniveaus

Naast de standaardmethode zijn de volgende methoden beschikbaar waarmee u logboeken op specifieke niveaus kunt schrijven:

Wijze Beschrijving
context.log.error() Hiermee schrijft u een gebeurtenis op foutniveau naar de logboeken.
context.log.warn() Hiermee schrijft u een gebeurtenis op waarschuwingsniveau naar de logboeken.
context.log.info() Hiermee schrijft u een gebeurtenis op informatieniveau naar de logboeken.
context.log.verbose() Hiermee schrijft u een gebeurtenis op traceringsniveau naar de logboeken.
Wijze Beschrijving
context.trace() Hiermee schrijft u een gebeurtenis op traceringsniveau naar de logboeken.
context.debug() Hiermee schrijft u een gebeurtenis op foutopsporingsniveau naar de logboeken.
context.info() Hiermee schrijft u een gebeurtenis op informatieniveau naar de logboeken.
context.warn() Hiermee schrijft u een gebeurtenis op waarschuwingsniveau naar de logboeken.
context.error() Hiermee schrijft u een gebeurtenis op foutniveau naar de logboeken.

Logboekniveau configureren

Azure Functions kunt u het drempelwaardeniveau definiëren dat moet worden gebruikt bij het bijhouden en weergeven van logboeken. Als u de drempelwaarde wilt instellen, gebruikt u de eigenschap in het bestand. Met deze eigenschap kunt u een standaardniveau definiëren dat wordt toegepast op alle functies of een drempelwaarde voor elke afzonderlijke functie. Zie De bewaking configureren voor Azure Functions voor meer informatie.

Aangepaste gegevens bijhouden

Standaard schrijft Azure Functions uitvoer als traceringen naar Application Insights. Voor meer controle kunt u in plaats daarvan de Application Insights Node.js SDK gebruiken om aangepaste logboeken, metrische gegevens en afhankelijkheden te verzenden naar uw Application Insights-exemplaar.

Notitie

Methoden in de Application Insights Node.js SDK kunnen na verloop van tijd veranderen. Er kunnen kleine syntaxisverschillen zijn ten opzichte van de voorbeelden die hier worden getoond. Zie de Application Insights Node.js SDK-documentatie voor de nieuwste voorbeelden van API-gebruik.

Voor gedistribueerde tracering in het Node.js v4-programmeermodel kunt u het pakket gebruiken in plaats van de Application Insights SDK. Dit pakket biedt automatische instrumentatie op basis van OpenTelemetry voor Azure Functions. Zie voor meer informatie de GitHub-opslagplaats OpenTelemetry Azure Functions Instrumentation voor Node.js.

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

Met de parameter wordt de aanroep-id van de functie ingesteld. Met deze instelling kunt u alle automatisch gegenereerde en aangepaste logboeken correleren voor een bepaalde functie-aanroep.

HTTP-triggers

HTTP- en webhooktriggers gebruiken aanvraag- en antwoordobjecten om HTTP-berichten weer te geven.

HTTP- en webhooktriggers gebruiken en objecten om HTTP-berichten weer te geven. De klassen vertegenwoordigen een subset van de ophaalstandaard met behulp van het pakket van Node.js.

HTTP-aanvraag

De aanvraag kan op verschillende manieren worden geopend:

  • Als tweede argument voor uw functie:

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

  • Vanuit de eigenschap:

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

  • Vanaf de benoemde invoerbindingen: deze optie werkt hetzelfde als elke niet-HTTP-binding. De bindingsnaam in moet overeenkomen met de sleutel op , of 'request1' in het volgende voorbeeld.

    {
      "name": "request1",
      "type": "httpTrigger",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": ["get", "post"]
    }
    
    • JavaScript
    • TypeScript
    module.exports = async function (context, request) {
        context.log(`Http function processed request for url "${context.bindings.request1.url}"`);
    

Het object heeft de volgende eigenschappen:

Eigenschap Typologie Beschrijving
method string Http-aanvraagmethode die wordt gebruikt om deze functie aan te roepen.
url string Aanvraag-URL.
headers Record<string, string> HTTP-aanvraagheaders. Dit object is hoofdlettergevoelig. Het wordt aanbevolen om in plaats daarvan te gebruiken , wat niet hoofdlettergevoelig is.
query Record<string, string> Queryreeks-parameter-sleutels en -waarden uit de URL.
params Record<string, string> Routeparameter sleutels en -waarden.
user HttpRequestUser \| null Object dat de aangemelde gebruiker vertegenwoordigt, hetzij via Functions-verificatie, SWA-verificatie of null wanneer een dergelijke gebruiker niet is aangemeld.
body Buffer \| string \| any Als het mediatype 'application/octet-stream' of 'multipart/*' is, is dit een buffer. Als de waarde een JSON-tekenreeks is die kan worden geparseerd, is het geparseerde object. Anders is een tekenreeks.
rawBody string De inhoud als een string. Ondanks de naam retourneert deze eigenschap geen buffer.
bufferBody Buffer Het lichaam als buffer.

De aanvraag kan worden geopend als het eerste argument voor uw handler voor een door HTTP geactiveerde functie.

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

Het object heeft de volgende eigenschappen:

Eigenschap Typologie Beschrijving
method string Http-aanvraagmethode die wordt gebruikt om deze functie aan te roepen.
url string Aanvraag-URL.
headers Headers HTTP-aanvraagheaders.
query URLSearchParams Queryreeks-parameter-sleutels en -waarden uit de URL.
params Record<string, string> Routeparameter sleutels en -waarden.
user HttpRequestUser \| null Object dat de aangemelde gebruiker vertegenwoordigt, hetzij via Functions-verificatie, SWA-verificatie of null wanneer een dergelijke gebruiker niet is aangemeld.
body ReadableStream \| null Body als leesbare stream.
bodyUsed boolean Een Booleaanse waarde die aangeeft of de hoofdtekst al is gelezen.

Om toegang te krijgen tot de hoofdtekst van een aanvraag of antwoord, kunnen de volgende methoden worden gebruikt:

Wijze Retourtype
arrayBuffer() Promise<ArrayBuffer>
blob() Promise<Blob>
formData() Promise<FormData>
json() Promise<unknown>
text() Promise<string>

Notitie

De lichaamsfuncties kunnen slechts één keer worden uitgevoerd. Volgende aanroepen worden afgehandeld met lege tekenreeksen/ArrayBuffers.

HTTP-antwoord

Het antwoord kan op verschillende manieren worden ingesteld:

  • Stel de eigenschap in:

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

  • Retourneer het antwoord: Als uw functie asynchroon is en u de bindingsnaam instelt in uw , kunt u het antwoord rechtstreeks retourneren in plaats van deze in te stellen.

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

  • Stel de benoemde uitvoerbinding in: deze optie werkt hetzelfde als elke niet-HTTP-binding. De naam van de binding moet overeenkomen met de sleutel in , of 'response1' in het volgende voorbeeld:

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

  • Aanroep : deze optie is afgeschaft. Het roept impliciet aan en kan niet worden gebruikt in een asynchrone functie.

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

Als u een nieuw object maakt bij het instellen van het antwoord, moet dat object overeenkomen met de interface, die de volgende eigenschappen heeft:

Eigenschap Typologie Beschrijving
headers (optioneel) HTTP-antwoordheaders.
cookies (optioneel) HTTP-antwoordcookies.
body (optioneel) HTTP-antwoordlichaam.
statusCode (optioneel) HTTP-antwoordstatuscode. Als dit niet is ingesteld, wordt standaard ingesteld op .
status (optioneel) Hetzelfde als . Deze eigenschap wordt genegeerd als is ingesteld.

U kunt het object ook wijzigen zonder het te overschrijven. Het standaardobject maakt gebruik van de interface, die naast de eigenschappen de volgende methoden ondersteunt:

Wijze Beschrijving
status() Hiermee stelt u de status in.
setHeader() Hiermee stelt u een koptekstveld in. OPMERKING: en worden ook ondersteund en doen hetzelfde.
getHeader() Een koptekstveld ophalen. OPMERKING: wordt ook ondersteund en doet hetzelfde.
removeHeader() Hiermee verwijdert u een koptekst.
type() Hiermee stelt u de header 'Content-Type' in.
send() Deze methode is afgeschaft. Het stelt de hoofdtekst in en roept aan om aan te geven dat een synchronisatiefunctie is voltooid. OPMERKING: wordt ook ondersteund en doet hetzelfde.
sendStatus() Deze methode is afgeschaft. Hiermee stelt u de statuscode en aanroepen in om aan te geven dat een synchronisatiefunctie is voltooid.
json() Deze methode is afgeschaft. Hiermee stelt u het 'inhoudstype' in op 'application/json', stelt u de hoofdtekst in en roept u aan om aan te geven dat een synchronisatiefunctie is voltooid.

Het antwoord kan op verschillende manieren worden ingesteld:

  • Als eenvoudige interface met type : Deze optie is de meest beknopte manier om antwoorden te retourneren.

    • JavaScript
    • TypeScript
    return { body: `Hello, world!` };
    

De interface heeft de volgende eigenschappen:

Eigenschap Typologie Beschrijving
body (optioneel) Http-antwoordtekst als een van , , , , , , , , , , of .
jsonBody (optioneel) Een http-antwoordtekst die kan worden geseriialiseerd met JSON. Indien ingesteld, wordt de eigenschap genegeerd ten gunste van deze eigenschap.
status (optioneel) HTTP-antwoordstatuscode. Als dit niet is ingesteld, wordt standaard ingesteld op .
headers (optioneel) HTTP-antwoordheaders.
cookies (optioneel) HTTP-antwoordcookies.
  • Als klasse met type : deze optie biedt helpermethoden voor het lezen en wijzigen van verschillende delen van het antwoord, zoals de headers.

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

De klasse accepteert een optioneel als argument voor de constructor en heeft de volgende eigenschappen:

Eigenschap Typologie Beschrijving
status number HTTP-antwoordstatuscode.
headers Headers HTTP-antwoordheaders.
cookies Cookie[] HTTP-antwoordcookies.
body ReadableStream | null Body als leesbare stream.
bodyUsed boolean Een Boolean die aangeeft of de inhoud al is gelezen.

HTTP streams

HTTP-streams is een functie waarmee u gemakkelijker grote gegevens kunt verwerken, OpenAI-antwoorden kunt streamen, dynamische inhoud kunt leveren en andere http-kernscenario's kunt ondersteunen. Hiermee kunt u aanvragen naar en antwoorden van HTTP-eindpunten streamen in uw Node.js functie-app. Gebruik HTTP-streams in scenario's waarin uw app realtime uitwisseling en interactie tussen client en server via HTTP vereist. U kunt ook HTTP-streams gebruiken om de beste prestaties en betrouwbaarheid voor uw apps te verkrijgen wanneer u HTTP gebruikt.

Belangrijk

HTTP-streams worden niet ondersteund in het v3-model. Voer een upgrade uit naar het v4-model om de HTTP-streamingfunctie te gebruiken. De bestaande typen in het programmeermodel v4 ondersteunen al verschillende manieren om de berichttekst te verwerken, inclusief als een stroom.

Vereisten

Streams inschakelen

Gebruik deze stappen om HTTP-streams in te schakelen in uw functie-app in Azure en in uw lokale projecten:

  1. Als u van plan bent grote hoeveelheden gegevens te streamen, wijzigt u de instelling FUNCTIONS_REQUEST_BODY_SIZE_LIMIT in Azure. De standaard toegestane maximale grootte van de hoofdtekst is , waardoor uw aanvragen worden beperkt tot een grootte van ~100 MB.

  2. Voor lokale ontwikkeling voegt u ook toe aan het local.settings.json-bestand.

  3. Voeg de volgende code toe aan uw app in elk bestand dat is opgenomen in het hoofdveld.

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

Stream-voorbeelden

In dit voorbeeld ziet u een door HTTP geactiveerde functie die gegevens ontvangt via een HTTP POST-aanvraag en de functie deze gegevens naar een opgegeven uitvoerbestand streamt:

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

In dit voorbeeld ziet u een door HTTP geactiveerde functie die de inhoud van een bestand streamt als reactie op binnenkomende HTTP GET-aanvragen:

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

Bekijk dit voorbeeld over GitHub voor een kant-en-klare voorbeeld-app met behulp van streams.

Overwegingen voor streaming

  • Gebruik dit om het maximale voordeel te krijgen van het gebruik van streams. U kunt nog steeds methoden blijven gebruiken, zoals , die altijd de hoofdtekst retourneren als een tekenreeks.

Haken

Hooks worden niet ondersteund in het v3-model. Voer een upgrade uit naar het v4-model om hooks te gebruiken.

Gebruik een hook om code uit te voeren op verschillende punten in de levenscyclus van Azure Functions. Hooks worden uitgevoerd in de volgorde waarin ze zijn geregistreerd en kunnen worden geregistreerd vanuit elk bestand in uw app. Er zijn momenteel twee niveaus van hooks: op app-niveau en op aanroepniveau.

Aanroephaken

Aanroephaken worden eenmaal uitgevoerd per aanroep van uw functie, ofwel voordat in een haak, of erna in een . Standaard wordt uw hook uitgevoerd voor alle triggertypen, maar u kunt ook filteren op type. In het volgende voorbeeld ziet u hoe u een aanroephook registreert en filtert op triggertype:

  • JavaScript
  • TypeScript
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}`
        );
    }
});

Het eerste argument voor de haakhandler is een contextobject dat specifiek is voor dat haaktype.

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
inputs De argumenten die aan de aanroep zijn doorgegeven.
functionHandler De handler voor de functieaanroep. Wijzigingen in deze waarde zijn van invloed op de functie zelf.
invocationContext Het aanroepcontext-object dat aan de functie is doorgegeven.
hookData De aanbevolen plek voor het opslaan en delen van gegevens tussen hooks binnen dezelfde context. U moet een unieke eigenschapsnaam gebruiken, zodat deze niet conflicteert met de gegevens van andere hooks.

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
inputs De argumenten die aan de aanroep zijn doorgegeven.
result Het resultaat van de functie. Wijzigingen in deze waarde zijn van invloed op het algehele resultaat van de functie.
error De fout die door de functie is opgeworpen, of null/undefined als er geen fout is. Wijzigingen in deze waarde zijn van invloed op het algehele resultaat van de functie.
invocationContext Het aanroepcontext-object dat aan de functie is doorgegeven.
hookData De aanbevolen plek voor het opslaan en delen van gegevens tussen hooks binnen dezelfde context. U moet een unieke eigenschapsnaam gebruiken, zodat deze niet conflicteert met de gegevens van andere hooks.

App hooks

App-hooks worden eenmaal per exemplaar van uw app uitgevoerd, hetzij tijdens het opstarten in een hook of tijdens beëindiging in een hook. Afsluitingshooks van apps hebben beperkte tijd om uitgevoerd te worden en worden niet in alle scenario's uitgevoerd.

De Azure Functions-runtime ondersteunt momenteel geen contextlogboekregistratie buiten een aanroep. Gebruik het Npm-pakket van Application Insights om gegevens te registreren tijdens hooks op app-niveau.

In het volgende voorbeeld worden app-hooks geregistreerd:

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

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

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

Het eerste argument voor de haakhandler is een contextobject dat specifiek is voor dat haaktype.

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
hookData De aanbevolen plek voor het opslaan en delen van gegevens tussen hooks binnen dezelfde context. U moet een unieke eigenschapsnaam gebruiken, zodat deze niet conflicteert met de gegevens van andere hooks.

Het object heeft de volgende eigenschappen:

Eigenschap Beschrijving
hookData De aanbevolen plek voor het opslaan en delen van gegevens tussen hooks binnen dezelfde context. U moet een unieke eigenschapsnaam gebruiken, zodat deze niet conflicteert met de gegevens van andere hooks.

Schalen en gelijktijdigheid

Standaard controleert Azure Functions de belasting van uw toepassing automatisch en worden er zo nodig meer hostexemplaren voor Node.js gemaakt. Azure Functions maakt gebruik van ingebouwde (niet door de gebruiker configureerbare) drempelwaarden voor verschillende triggertypen om te bepalen wanneer exemplaren moeten worden toegevoegd, zoals de leeftijd van berichten en de wachtrijgrootte voor QueueTrigger. Zie Hoe de Verbruiks- en Premium-abonnementen werken voor meer informatie.

Dit schaalgedrag is voldoende voor veel Node.js toepassingen. Voor CPU-afhankelijke toepassingen kunt u de prestaties verder verbeteren door gebruik te maken van werkprocessen in meerdere talen. U kunt het aantal werkprocessen per host verhogen van de standaardwaarde van 1 tot maximaal 10 met behulp van de FUNCTIONS_WORKER_PROCESS_COUNT toepassingsinstelling. Azure Functions probeert vervolgens gelijktijdige functieaanroepen over deze werknemers gelijkmatig te verdelen. Dit gedrag maakt het minder waarschijnlijk dat een CPU-intensieve functie voorkomt dat andere functies worden uitgevoerd. De instelling is van toepassing op elke host die Azure Functions maakt bij het uitschalen van uw toepassing om aan de vraag te voldoen.

Waarschuwing

Gebruik de instelling voorzichtig. Meerdere processen die in hetzelfde exemplaar worden uitgevoerd, kunnen leiden tot onvoorspelbaar gedrag en kunnen de laadtijden van de functie verhogen. Als u deze instelling gebruikt, raden we u ten zeerste aan deze nadelen te compenseren door uit te voeren vanuit een pakketbestand.

Node-versie

U kunt de huidige versie die door de runtime wordt gebruikt zien door vanuit een functie te loggen. Zie voor een lijst met Node.js versies die door elk programmeermodel worden ondersteund.

De Node-versie instellen

De manier waarop u uw Node.js-versie bijwerken, is afhankelijk van het besturingssysteem waarop uw functie-app wordt uitgevoerd.

Wanneer deze wordt uitgevoerd op Windows, wordt de Node.js versie ingesteld door de toepassingsinstelling WEBSITE_NODE_DEFAULT_VERSION. Deze instelling kan worden bijgewerkt met behulp van de Azure CLI of in de Azure-portal.

Zie Ondersteunde versies voor meer informatie over Node.js versies.

Voordat u uw Node.js-versie bijwerken, moet u ervoor zorgen dat uw functie-app wordt uitgevoerd op de nieuwste versie van de Azure Functions runtime. Zie Migrate-apps van Azure Functions versie 3.x naar versie 4.x als u uw runtime-versie wilt upgraden.

Voer de opdracht Azure CLI az functionapp config appsettings set uit om de Node.js-versie bij te werken voor uw functie-app die wordt uitgevoerd op Windows:

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

Hiermee stelt u de toepassingsinstelling in op de ondersteunde LTS-versie van .

Nadat de wijzigingen zijn aangebracht, wordt de functie-app opnieuw opgestart. Zie het ondersteuningsbeleid voor Language Runtime voor meer informatie over de ondersteuning van Functions voor Node.js.

Omgevingsvariabelen

Omgevingsvariabelen kunnen handig zijn voor operationele geheimen (verbindingsreeks s, sleutels, eindpunten, enzovoort) of omgevingsinstellingen zoals profileringsvariabelen. U kunt omgevingsvariabelen toevoegen in zowel uw lokale als cloudomgevingen en deze openen via uw functiecode.

In het volgende voorbeeld wordt de omgevingsvariabele in een logboek opgeslagen:

  • JavaScript
  • TypeScript
module.exports = async function (context) {
  context.log(`WEBSITE_SITE_NAME: ${process.env["WEBSITE_SITE_NAME"]}`);
};
  • JavaScript
  • TypeScript
async function timerTrigger1(myTimer, context) {
  context.log(`WEBSITE_SITE_NAME: ${process.env["WEBSITE_SITE_NAME"]}`);
}

In de lokale ontwikkelomgeving

Wanneer u lokaal uitvoert, bevat uw functions-project een bestand waarin u uw omgevingsvariabelen opslaat in het object.

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

In Azure cloudomgeving

Wanneer u in Azure uitvoert, kunt u met de functie-app Application-instellingen, zoals serviceverbindingsreeksen, instellen en gebruiken en deze instellingen weergeven als omgevingsvariabelen tijdens de uitvoering.

Er zijn verschillende manieren waarop u instellingen van een functie app kunt toevoegen, bijwerken en verwijderen:

Voor wijzigingen in de instellingen van de functie-app moet uw functie-app opnieuw worden gestart.

Omgevingsvariabelen voor workers

Er zijn verschillende omgevingsvariabelen voor Functions die specifiek zijn voor Node.js:

languageWorkers-knooppuntargumenten

Met deze instelling kunt u aangepaste argumenten opgeven bij het starten van uw Node.js proces. Het wordt meestal lokaal gebruikt om de werkrol te starten in de foutopsporingsmodus, maar kan ook worden gebruikt in Azure als u aangepaste argumenten nodig hebt.

Waarschuwing

Vermijd indien mogelijk het gebruik van languageWorkers__node__arguments in Azure omdat dit een negatief effect kan hebben op koude begintijden. In plaats van vooraf opgewarmde werknemers te gebruiken, moet de runtime een nieuwe werknemer vanuit het niets starten met uw aangepaste argumenten.

logboekbeheerlogLevelWerknemer

Met deze instelling wordt het standaardlogboekniveau voor Node.js specifieke werklogboeken aangepast. Standaard worden alleen waarschuwings- of foutlogboeken weergegeven, maar u kunt deze instellen op of om problemen met de Node.js-worker op te sporen. Zie Logboekniveaus configureren voor meer informatie.

ECMAScript-modules (voorbeeld)

Notitie

Aangezien ECMAScript-modules momenteel een preview-functie zijn in Node.js 14 of hoger in Azure Functions.

ECMAScript-modules (ES-modules ) zijn het nieuwe officiële standaardmodulesysteem voor Node.js. Tot nu toe gebruiken de codevoorbeelden in dit artikel de CommonJS-syntaxis. Wanneer u Azure Functions uitvoert in Node.js 14 of hoger, kunt u ervoor kiezen om uw functies te schrijven met behulp van de syntaxis van ES-modules.

Als u ES-modules in een functie wilt gebruiken, wijzigt u de bestandsnaam in een extensie. Het volgende index.mjs-bestand is een door HTTP geactiveerde functie die gebruikmaakt van de syntaxis van ES-modules om de bibliotheek te importeren en een waarde te retourneren.

  • JavaScript
  • TypeScript
import { v4 as uuidv4 } from "uuid";

async function httpTrigger1(context, request) {
  context.res.body = uuidv4();
}

export default httpTrigger;
  • JavaScript
  • TypeScript
import { v4 as uuidv4 } from "uuid";

async function httpTrigger1(request, context) {
  return { body: uuidv4() };
}

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

Functieinvoerpunt configureren

De eigenschappen en kunnen worden gebruikt om de locatie en naam van uw geëxporteerde functie te configureren. De eigenschap is vereist wanneer u TypeScript gebruikt en moet verwijzen naar het gecompileerde JavaScript.

Het gebruiken van

Standaard wordt een JavaScript-functie uitgevoerd vanuit , een bestand dat dezelfde bovenliggende map deelt als de bijbehorende map.

kan worden gebruikt om een mapstructuur op te halen die eruitziet als in het volgende voorbeeld:

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

De for moet een eigenschap bevatten die verwijst naar het bestand met de geëxporteerde functie die moet worden uitgevoerd.

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

Het gebruiken van

In het v3-model moet een functie worden geëxporteerd met behulp van om gevonden en uitgevoerd te kunnen worden. Standaard is de functie die wordt uitgevoerd wanneer deze wordt geactiveerd, de enige export uit dat bestand, de export met de naam of de export met de naam . In het volgende voorbeeld wordt in ingesteld op een aangepaste waarde: "logHello".

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

module.exports = { logHello };

Lokale foutopsporing

U wordt aangeraden VS Code te gebruiken voor lokale foutopsporing, waardoor uw Node.js proces automatisch wordt gestart in de foutopsporingsmodus en wordt gekoppeld aan het proces voor u. Zie De functie lokaal uitvoeren voor meer informatie.

Als u een ander programma gebruikt voor debugging of als u het Node.js-proces handmatig in de debugmodus wilt starten, voegt u toe onder in uw local.settings.json. Het argument geeft aan Node.js standaard te luisteren naar een foutopsporingsclient op poort 9229. Zie de handleiding voor Node.js foutopsporing voor meer informatie.

Aanbevelingen

In deze sectie worden verschillende impactvolle patronen beschreven voor Node.js apps die u wordt aangeraden te volgen.

App Service-abonnementen met één vCPU kiezen

Wanneer u een functie-app maakt die gebruikmaakt van het App Service-plan, raden we u aan een abonnement met één vCPU te selecteren in plaats van een plan met meerdere vCPU's. Tegenwoordig worden Node.js functies efficiënter uitgevoerd op VM's met één vCPU en levert het gebruik van grotere VM's niet de verwachte prestatieverbeteringen op. Indien nodig kunt u handmatig uitschalen door meer VM-exemplaren met één vCPU toe te voegen of door automatische schaalaanpassing in te schakelen. Zie Het aantal exemplaren handmatig of automatisch schalen voor meer informatie.

Uitvoeren vanuit een pakketbestand

Wanneer u Azure Functions ontwikkelt in het serverloze hostingmodel, is koude start een realiteit. Koude start verwijst naar de eerste keer dat uw functie-app wordt gestart na een periode van inactiviteit, wat langer duurt om te starten. Voor Node.js apps met grote afhankelijkheidsstructuren in het bijzonder kan koude start aanzienlijk zijn. Als u het koude startproces wilt versnellen, voert u uw functies zo mogelijk uit als een pakketbestand . Veel implementatiemethoden gebruiken dit model standaard, maar als u te maken hebt met grote koude starts, moet u controleren of het systeem op deze manier functioneert.

Eén statische client gebruiken

Wanneer u een servicespecifieke client in een Azure Functions-toepassing gebruikt, maakt u geen nieuwe client met elke functieaanroep omdat u verbindingslimieten kunt bereiken. Maak in plaats daarvan één statische client in het globale bereik. Zie beheerverbindingen in Azure Functions voor meer informatie.

Gebruiken en

Bij het schrijven van Azure Functions in Node.jsmoet u code schrijven met de trefwoorden async en await. Het schrijven van code met behulp van en in plaats van callbacks of met Promise helpt bij het voorkomen van twee veelvoorkomende problemen:

  • Het genereren van onopgevangen uitzonderingen die het Node.js proces laten crashen, dat mogelijk de uitvoering van andere functies beïnvloedt.
  • Onverwacht gedrag, zoals ontbrekende logregels van , veroorzaakt door asynchrone aanroepen die niet goed worden gewacht.

In het volgende voorbeeld wordt de asynchrone methode aangeroepen met een error-first callback-functie als de tweede parameter. Deze code veroorzaakt beide problemen die eerder zijn genoemd. Een uitzondering die niet expliciet in het juiste bereik wordt opgevangen, kan het hele proces laten crashen (probleem #1). Retourneren zonder ervoor te zorgen dat de callback is voltooid, betekent dat het HTTP-antwoord soms een lege hoofdtekst heeft (probleem #2).

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

In het volgende voorbeeld wordt de asynchrone methode aangeroepen met een error-first callback-functie als de tweede parameter. Deze code veroorzaakt beide problemen die eerder zijn genoemd. Een uitzondering die niet expliciet in het juiste bereik wordt opgevangen, kan het hele proces laten crashen (probleem #1). Het aanroepen van de afgeschafte methode buiten het bereik van de callback kan aangeven dat de functie is voltooid voordat het bestand wordt gelezen (probleem 2). In dit voorbeeld resulteert het aanroepen van te vroeg in ontbrekende logboekvermeldingen die beginnen met .

  • JavaScript
  • TypeScript
// 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();
};

Gebruik de en trefwoorden om beide problemen te voorkomen. De meeste API's in het Node.js ecosysteem zijn geconverteerd naar ondersteuningsbeloften in een bepaalde vorm. Vanaf v14 biedt Node.js bijvoorbeeld een API om de callback-API te vervangen.

In het volgende voorbeeld mislukken eventuele niet-verwerkte uitzonderingen die worden gegenereerd tijdens de uitvoering van de functie alleen de afzonderlijke aanroep die de uitzondering heeft gegenereerd. Het trefwoord betekent dat de volgende stappen alleen worden uitgevoerd nadat het is voltooid.

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

Met en , u hoeft ook niet de callback aan te roepen.

  • JavaScript
  • TypeScript
// 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}`);
};

Problemen oplossen

Raadpleeg de handleiding voor het oplossen van problemen met Node.js.

Volgende stappen

Voor meer informatie raadpleegt u de volgende bronnen: