Eseguire la migrazione alla versione 4 del modello di programmazione Node.js per Funzioni di Azure

Questo articolo illustra le differenze tra la versione 3 e la versione 4 del modello di programmazione Node.js e come aggiornare un'app v3 esistente. Se si vuole creare una nuova app v4 invece di aggiornare un'app v3 esistente, vedere l'esercitazione per Visual Studio Code (VS Code) o Funzioni di Azure Core Tools. Questo articolo usa gli avvisi "suggerimento" per evidenziare le azioni concrete più importanti da eseguire per aggiornare l'app.

La versione 4 è progettata per offrire agli sviluppatori Node.js i vantaggi seguenti:

  • Offrire agli sviluppatori Node.js un'esperienza familiare e intuitiva.
  • Rendere flessibile la struttura di file con supporto per la personalizzazione completa.
  • Passare a un approccio incentrato sul codice per definire la configurazione delle funzioni.

Considerazioni

  • Il modello di programmazione Node.js non deve essere confuso con il runtime di Funzioni di Azure:
    • Modello di programmazione: definisce come creare il codice ed è specifico di JavaScript e TypeScript.
    • Runtime: definisce il comportamento sottostante di Funzioni di Azure e viene condiviso in tutti i linguaggi.
  • La versione del modello di programmazione è strettamente associata alla versione del @azure/functions pacchetto npm. Il controllo delle versioni viene eseguito indipendentemente dal runtime. Sia il runtime che il modello di programmazione usano il numero 4 come versione principale più recente, ma questa è una coincidenza.
  • Non è possibile combinare i modelli di programmazione v3 e v4 nella stessa app per le funzioni. Non appena si registra una funzione v4 nell'app, tutte le funzioni v3 registrate nei file function.json vengono ignorate.

Requisiti

La versione 4 del modello di programmazione Node.js richiede le versioni minime seguenti:

Includere il pacchetto npm

Nella versione 4 il @azure/functions pacchetto npm contiene il codice sorgente primario che esegue il backup del modello di programmazione Node.js. Nelle versioni precedenti, il codice fornito direttamente in Azure e il pacchetto npm aveva solo i tipi TypeScript. È ora necessario includere questo pacchetto per le app TypeScript e JavaScript. È possibile includere il pacchetto per le app v3 esistenti, ma non è obbligatorio.

Suggerimento

Assicurarsi che il @azure/functions pacchetto sia elencato nella dependencies sezione (non devDependencies) del file package.json . È possibile installare v4 usando il comando seguente:

npm install @azure/functions

Impostare il punto di ingresso dell'app

Nella versione 4 del modello di programmazione è possibile strutturare il codice desiderato. Gli unici file necessari nella radice dell'app sono host.json e package.json.

In caso contrario, definire la struttura del file impostando il main campo nel file package.json . È possibile impostare il main campo su un singolo file o più file usando un modello GLOB. La tabella seguente mostra i valori di esempio per il main campo:

Esempio Descrizione
src/index.js Registrare le funzioni da un singolo file radice.
src/functions/*.js Registrare ogni funzione dal proprio file.
src/{index.js,functions/*.js} Combinazione in cui si registra ogni funzione dal proprio file, ma è ancora disponibile un file radice per il codice generale a livello di app.
Esempio Descrizione
dist/src/index.js Registrare le funzioni da un singolo file radice.
dist/src/functions/*.js Registrare ogni funzione dal proprio file.
dist/src/{index.js,functions/*.js} Combinazione in cui si registra ogni funzione dal proprio file, ma è ancora disponibile un file radice per il codice generale a livello di app.

Suggerimento

Assicurarsi di definire un main campo nel file package.json .

Cambiare l'ordine degli argomenti

L'input del trigger, invece del contesto di chiamata, è ora il primo argomento del gestore di funzioni. Il contesto di chiamata, ora il secondo argomento, è semplificato nella versione 4 e non è necessario come input del trigger. È possibile lasciarlo disattivato se non lo si usa.

Suggerimento

Cambiare l'ordine degli argomenti. Ad esempio, se si usa un trigger HTTP, passare (context, request) a (request, context) o solo (request) se non si usa il contesto.

Definire la funzione nel codice

Non è più necessario creare e gestire i file di configurazione function.json separati. È ora possibile definire completamente le funzioni direttamente nei file TypeScript o JavaScript. Inoltre, molte proprietà ora hanno impostazioni predefinite in modo che non sia necessario specificarle ogni volta.

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

Suggerimento

Spostare la configurazione dal file function.json al codice. Il tipo del trigger corrisponde a un metodo sull'oggetto app nel nuovo modello. Ad esempio, se si usa un httpTrigger tipo in function.json, chiamare app.http() nel codice per registrare la funzione. Se si usa timerTrigger, chiamare app.timer().

Esaminare l'utilizzo del contesto

Nella versione 4 l'oggetto context è semplificato per ridurre la duplicazione e semplificare la scrittura di unit test. Ad esempio, è stato semplificato l'input e l'output primario in modo che siano accessibili solo come argomento e valore restituito del gestore di funzioni.

Non è più possibile accedere all'input e all'output primario sull'oggetto context , ma è comunque necessario accedere agli input e agli output secondari sull'oggetto context . Per altre informazioni sugli input e gli output secondari, vedere la guida per sviluppatori Node.js.

Ottenere l'input primario come argomento

L'input primario viene chiamato anche trigger ed è l'unico input o output richiesto. È necessario avere un solo trigger (e uno).

La versione 4 supporta solo un modo per ottenere l'input del trigger, come primo argomento:

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

Suggerimento

Assicurarsi di non usare context.req o context.bindings di ottenere l'input.

Impostare l'output primario come valore restituito

La versione 4 supporta solo un modo per impostare l'output primario, tramite il valore restituito:

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

Suggerimento

Assicurarsi di restituire sempre l'output nel gestore di funzioni, anziché impostarlo con l'oggetto context .

Registrazione del contesto

Nella versione 4 i metodi di registrazione sono stati spostati nell'oggetto radice context , come illustrato nell'esempio seguente. Per altre informazioni sulla registrazione, vedere la guida per sviluppatori Node.js.

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

Creare un contesto di test

La versione 3 non supporta la creazione di un contesto di chiamata all'esterno del runtime di Funzioni di Azure, quindi la creazione di unit test può essere difficile. La versione 4 consente di creare un'istanza del contesto di chiamata, anche se le informazioni durante i test non sono dettagliate a meno che non vengano aggiunte manualmente.

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

Esaminare l'utilizzo dei tipi HTTP

I tipi di richiesta e risposta HTTP sono ora un subset dello standard di recupero. Non sono più unici per Funzioni di Azure.

I tipi usano il undici pacchetto in Node.js. Questo pacchetto segue lo standard di recupero ed è attualmente integrato nel core Node.js.

HttpRequest

  • Testo. È possibile accedere al corpo usando un metodo specifico del tipo che si vuole ricevere:

    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();
    
  • Intestazione:

    const header = request.headers.get('content-type');
    
  • Parametro di query:

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

HttpResponse

  • Stato:

    return { status: 200 };
    
  • Corpo:

    Usare la body proprietà per restituire la maggior parte dei tipi, ad esempio o stringBuffer:

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

    Usare la jsonBody proprietà per il modo più semplice per restituire una risposta JSON:

    return { jsonBody: { hello: "world" } };
    
  • Intestazione. È possibile impostare l'intestazione in due modi, a seconda che si usi la HttpResponse classe o l'interfaccia HttpResponseInit :

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

Suggerimento

Aggiornare qualsiasi logica usando i tipi di richiesta o risposta HTTP in modo che corrispondano ai nuovi metodi.

Suggerimento

Aggiornare qualsiasi logica usando i tipi di richiesta o risposta HTTP in modo che corrispondano ai nuovi metodi. È consigliabile ottenere errori di compilazione TypeScript per identificare se si usano metodi precedenti.

Risoluzione dei problemi

Vedere la guida alla risoluzione dei problemi di Node.js.