Migrera till version 4 av Node.js-programmeringsmodellen för Azure Functions

I den här artikeln beskrivs skillnaderna mellan version 3 och version 4 av node.js-programmeringsmodellen och hur du uppgraderar en befintlig v3-app. Om du vill skapa en ny v4-app i stället för att uppgradera en befintlig v3-app kan du läsa självstudien för antingen Visual Studio Code (VS Code) eller Azure Functions Core Tools. Den här artikeln använder tipsaviseringar för att belysa de viktigaste konkreta åtgärder som du bör vidta för att uppgradera din app.

Version 4 är utformad för att ge Node.js-utvecklare följande fördelar:

  • Ge Node.js-utvecklare en välbekant och intuitiv upplevelse.
  • Gör filstrukturen flexibel med stöd för fullständig anpassning.
  • Växla till en kodcentrerad metod för att definiera funktionskonfiguration.

Att tänka på

  • Programmeringsmodellen Node.js bör inte förväxlas med Azure Functions-körningen:
    • Programmeringsmodell: Definierar hur du skapar din kod och är specifik för JavaScript och TypeScript.
    • Körning: Definierar underliggande beteende för Azure Functions och delas mellan alla språk.
  • Versionen av programmeringsmodellen är strikt kopplad till versionen av @azure/functions npm-paketet. Den är versionshanterad oberoende av körningen. Både körningen och programmeringsmodellen använder nummer 4 som sin senaste huvudversion, men det är en tillfällighet.
  • Du kan inte blanda programmeringsmodellerna v3 och v4 i samma funktionsapp. Så snart du registrerar en v4-funktion i din app ignoreras alla v3-funktioner som är registrerade i function.json-filer .

Behov

Version 4 av node.js-programmeringsmodellen kräver följande lägsta versioner:

Inkludera npm-paketet

I v4 @azure/functions innehåller npm-paketet den primära källkoden som stöder programmeringsmodellen Node.js. I tidigare versioner hade koden som levererades direkt i Azure och npm-paketet endast TypeScript-typerna. Nu måste du inkludera det här paketet för både TypeScript- och JavaScript-appar. Du kan inkludera paketet för befintliga v3-appar, men det krävs inte.

Dricks

Kontrollera att @azure/functions paketet visas i avsnittet (inte devDependencies) i dependencies filen package.json. Du kan installera v4 med hjälp av följande kommando:

npm install @azure/functions

Ange startpunkt för din app

I v4 i programmeringsmodellen kan du strukturera koden hur du vill. De enda filer som du behöver i appens rot är host.json och package.json.

Annars definierar du filstrukturen genom att ange fältet main i filen package.json . Du kan ange fältet main till en enskild fil eller flera filer med hjälp av ett globmönster. I följande tabell visas exempelvärden för fältet main :

Exempel beskrivning
src/index.js Registrera funktioner från en enda rotfil.
src/functions/*.js Registrera varje funktion från en egen fil.
src/{index.js,functions/*.js} En kombination där du registrerar varje funktion från en egen fil, men du fortfarande har en rotfil för allmän kod på appnivå.
Exempel beskrivning
dist/src/index.js Registrera funktioner från en enda rotfil.
dist/src/functions/*.js Registrera varje funktion från en egen fil.
dist/src/{index.js,functions/*.js} En kombination där du registrerar varje funktion från en egen fil, men du fortfarande har en rotfil för allmän kod på appnivå.

Dricks

Se till att du definierar ett main fält i filen package.json .

Växla ordning på argument

Utlösarindata i stället för anropskontexten är nu det första argumentet för funktionshanteraren. Anropskontexten, nu det andra argumentet, förenklas i v4 och är inte lika obligatorisk som utlösarindata. Du kan låta det vara avstängt om du inte använder det.

Dricks

Ändra ordning på argumenten. Om du till exempel använder en HTTP-utlösare växlar (context, request) du till antingen (request, context) eller bara (request) om du inte använder kontexten.

Definiera din funktion i kod

Du behöver inte längre skapa och underhålla dessa separata function.json-konfigurationsfiler . Nu kan du helt definiera dina funktioner direkt i TypeScript- eller JavaScript-filerna. Dessutom har många egenskaper nu standardvärden så att du inte behöver ange dem varje gång.

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

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

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

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

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

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

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

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

Dricks

Flytta konfigurationen från filen function.json till koden. Typen av utlösare motsvarar en metod för app objektet i den nya modellen. Om du till exempel använder en httpTrigger typ i function.json anropar app.http() du koden för att registrera funktionen. Om du använder timerTriggeranropar app.timer()du .

Granska din användning av kontext

I v4 context förenklas objektet för att minska dupliceringen och göra det enklare att skriva enhetstester. Vi effektiviserade till exempel de primära indata och utdata så att de endast används som argument och returnerar värdet för funktionshanteraren.

Du kan inte längre komma åt de primära indata och utdata på context objektet, men du måste fortfarande komma åt sekundära indata och utdata på context objektet. Mer information om sekundära indata och utdata finns i utvecklarguiden för Node.js.

Hämta de primära indata som ett argument

Den primära indata kallas också utlösaren och är den enda nödvändiga indata eller utdata. Du måste ha en (och bara en) utlösare.

Version 4 stöder bara ett sätt att hämta utlösarindata, som det första argumentet:

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

Dricks

Kontrollera att du inte använder context.req eller context.bindings för att hämta indata.

Ange de primära utdata som ditt returvärde

Version 4 stöder endast ett sätt att ange primära utdata via returvärdet:

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

Dricks

Kontrollera att du alltid returnerar utdata i funktionshanteraren i stället för att ange det med context objektet.

Kontextloggning

I v4 flyttades loggningsmetoder till rotobjektet context enligt följande exempel. Mer information om loggning finns i utvecklarguiden för Node.js.

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

Skapa en testkontext

Version 3 stöder inte att skapa en anropskontext utanför Azure Functions-körningen, så det kan vara svårt att redigera enhetstester. Med version 4 kan du skapa en instans av anropskontexten, men informationen under testerna är inte detaljerad om du inte lägger till den själv.

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

Granska din användning av HTTP-typer

HTTP-begärande- och svarstyperna är nu en delmängd av hämtningsstandarden. De är inte längre unika för Azure Functions.

Typerna undici använder paketet i Node.js. Det här paketet följer hämtningsstandarden och håller för närvarande på att integreras i Node.js Core.

HttpRequest

  • Brödtext. Du kan komma åt brödtexten med hjälp av en metod som är specifik för den typ som du vill ta emot:

    const body = await request.text();
    const body = await request.json();
    const body = await request.formData();
    const body = await request.arrayBuffer();
    const body = await request.blob();
    
  • Rubrik:

    const header = request.headers.get('content-type');
    
  • Frågeparameter:

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

HttpResponse

  • Status:

    return { status: 200 };
    
  • Brödtext:

    Använd egenskapen body för att returnera de flesta typer som en string eller Buffer:

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

    Använd egenskapen jsonBody för det enklaste sättet att returnera ett JSON-svar:

    return { jsonBody: { hello: "world" } };
    
  • Sidhuvud. Du kan ange rubriken på två sätt, beroende på om du använder HttpResponse klassen eller HttpResponseInit gränssnittet:

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

Dricks

Uppdatera logiken med hjälp av HTTP-begärande- eller svarstyperna för att matcha de nya metoderna.

Dricks

Uppdatera logiken med hjälp av HTTP-begärande- eller svarstyperna för att matcha de nya metoderna. Du bör få TypeScript-byggfel som hjälper dig att identifiera om du använder gamla metoder.

Felsöka

Se felsökningsguiden för Node.js.