Guida per gli sviluppatori JavaScript di Funzioni di Azure

L'esperienza JavaScript per Funzioni di Azure semplifica l'esportazione di una funzione, che viene passata come oggetto context per la comunicazione con il runtime e per la ricezione e l'invio di dati tramite associazioni.

Questo articolo presuppone che l'utente abbia già letto Guida di riferimento per gli sviluppatori di Funzioni di Azure.

Esportazione di una funzione

Tutte le funzioni JavaScript devono esportare una singola function tramite module.exports per consentire al runtime di trovare la funzione ed eseguirla. Questa funzione deve sempre includere un oggetto context .

// You must include a context, but other arguments are optional
module.exports = function(context) {
    // Additional inputs can be accessed by the arguments property
    if(arguments.length === 4) {
        context.log('This function has 4 inputs');
    }
};
// or you can include additional inputs in your arguments
module.exports = function(context, myTrigger, myInput, myOtherInput) {
    // function logic goes here :)
};

Le associazioni di direction === "in" vengono passate come argomenti della funzione, pertanto è possibile usare arguments per gestire in modo dinamico nuovi input, ad esempio usando arguments.length per l'iterazione di tutti gli input. Questa funzionalità è utile se si ha solo un trigger e nessun input aggiuntivo, in quanto consente di accedere ai dati del trigger in modo prevedibile senza fare riferimento all'oggetto context.

Gli argomenti vengono sempre passati insieme alla funzione nell'ordine in cui sono indicati nel file function.json, anche se non vengono specificati nell'istruzione exports. Se ad esempio si ha function(context, a, b) e viene modificato in function(context, a), è comunque possibile ottenere il valore di b nel codice della funzione facendo riferimento a arguments[3].

Anche tutte le associazioni, indipendentemente dalla direzione, vengono passate sull'oggetto context (vedere lo script seguente).

Oggetto context

Il runtime usa un oggetto context per passare dati dalla e alla funzione e consentire la comunicazione con il runtime.

L'oggetto context è sempre il primo parametro di una funzione e deve essere incluso, in quanto contiene i metodi necessari per usare correttamente il runtime, ad esempio context.done e context.log. È possibile assegnare all'oggetto un nome qualsiasi, ad esempio ctx o c.

// You must include a context, but other arguments are optional
module.exports = function(context) {
    // function logic goes here :)
};

Proprietà context.bindings

context.bindings

Restituisce un oggetto denominato che contiene tutti i dati di input e output. Data la seguente definizione di associazione in function.json, è ad esempio possibile accedere al contenuto della coda tramite l'oggetto context.bindings.myInput.

{
    "type":"queue",
    "direction":"in",
    "name":"myInput"
    ...
}
// myInput contains the input data, which may have properties such as "name"
var author = context.bindings.myInput.name;
// Similarly, you can set your output data
context.bindings.myOutput = { 
        some_text: 'hello world', 
        a_number: 1 };

Metodo context.done

context.done([err],[propertyBag])

Comunica al runtime che l'esecuzione è stata completata. La chiamata a context.done è necessaria. In caso contrario, il runtime non saprà mai che la funzione è stata completata e l'esecuzione raggiungerà il timeout.

Il metodo context.done consente di passare di nuovo al runtime sia un errore definito dall'utente sia un contenitore delle proprietà con proprietà che sovrascriveranno quelle presenti nell'oggetto context.bindings.

// Even though we set myOutput to have:
//  -> text: hello world, number: 123
context.bindings.myOutput = { text: 'hello world', number: 123 };
// If we pass an object to the done function...
context.done(null, { myOutput: { text: 'hello there, world', noNumber: true }});
// the done method will overwrite the myOutput binding to be: 
//  -> text: hello there, world, noNumber: true

Metodo context.log

context.log(message)

Consente di scrivere nei log della console in streaming a livello di traccia predefinito. In context.log sono disponibili altri metodi di registrazione che consentono di scrivere nel log della console ad altri livelli di traccia:

Metodo Descrizione
error(messaggio) Scrive nella registrazione a livello di errore o inferiore.
warn(messaggio) Scrive nella registrazione a livello di avviso o inferiore.
info(messaggio) Scrive nella registrazione a livello di informazioni o inferiore.
verbose(messaggio) Scrive nella registrazione a livello dettagliato.

L'esempio seguente scrive nella console a livello di traccia di avviso:

context.log.warn("Something has happened."); 

È possibile impostare la soglia del livello di traccia per la registrazione nel file host.json o disattivarla. Per altre informazioni su come scrivere nei log, vedere la sezione successiva.

Associazione del tipo di dati

Per definire il tipo di dati per un'associazione di input, usare la proprietà dataType nella definizione dell'associazione. Ad esempio, per leggere il contenuto di una richiesta HTTP in formato binario, usare il tipo binary:

{
    "type": "httpTrigger",
    "name": "req",
    "direction": "in",
    "dataType": "binary"
}

Altre opzioni per dataType sono stream e string.

Scrittura dell'output di traccia nella console

In Funzioni usare i metodi context.log per scrivere l'output di traccia nella console. A questo punto, non è possibile usare console.log per scrivere nella console.

Quando si chiama context.log(), il messaggio viene scritto nella console a livello di traccia predefinito, ovvero il livello di traccia info. Il codice seguente scrive nella console a livello di traccia informazioni:

context.log({hello: 'world'});  

Il codice precedente equivale al seguente:

context.log.info({hello: 'world'});  

Il codice seguente scrive nella console a livello di errore:

context.log.error("An error has occurred.");  

Poiché error è il livello di traccia più alto, questa traccia viene scritta nell'output a tutti i livelli di traccia, fintantoché la registrazione è abilitata.

Tutti i metodi context.log supportano lo stesso formato di parametri supportato dal metodo Node.js util.format. Si consideri il codice seguente, che scrive nella console usando il livello di traccia predefinito:

context.log('Node.js HTTP trigger function processed a request. RequestUri=' + req.originalUrl);
context.log('Request Headers = ' + JSON.stringify(req.headers));

È possibile scrivere lo stesso codice anche nel formato seguente:

context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);
context.log('Request Headers = ', JSON.stringify(req.headers));

Configurare il livello di traccia per la registrazione della console

Funzioni consente di definire la soglia del livello di traccia per la scrittura nella console; questo consente di controllare più facilmente il modo in cui le tracce vengono scritte nella console dalle funzioni. Per impostare la soglia per tutte le tracce scritte nella console, usare la proprietà tracing.consoleLevel nel file host.json. Questa impostazione si applica a tutte le funzioni dell'app per le funzioni. L'esempio seguente imposta la soglia di traccia per abilitare la registrazione dettagliata:

{ 
    "tracing": {      
        "consoleLevel": "verbose"     
    }
}  

I valori di consoleLevel corrispondono ai nomi dei metodi context.log. Per disabilitare tutta la registrazione traccia nella console, impostare consoleLevel su off. Per altre informazioni sul file host.json, vedere l'argomento di riferimento host.json.

Trigger e associazioni HTTP

I trigger e i webhook HTTP e le associazioni di output HTTP usano oggetti di richiesta e risposta per rappresentare la messaggistica HTTP.

Oggetto della richiesta

Di seguito sono elencate le proprietà dell'oggetto request:

Proprietà Descrizione
body Oggetto che contiene il corpo della richiesta.
headers Oggetto che contiene le intestazioni della richiesta.
method Metodo HTTP della richiesta.
originalUrl URL della richiesta.
params Oggetto che contiene i parametri di routing della richiesta.
query Oggetto che contiene i parametri di query della richiesta.
rawBody Il corpo del messaggio sotto forma di stringa.

Oggetto della risposta

Di seguito sono elencate le proprietà dell'oggetto response:

Proprietà Descrizione
body Oggetto che contiene il corpo della risposta.
headers Oggetto che contiene le intestazioni della risposta.
isRaw Indica che la formattazione viene ignorata per la risposta.
Stato Codice di stato HTTP della risposta.

Accesso a richiesta e risposta

Quando si lavora con i trigger HTTP, è possibile accedere agli oggetti richiesta e risposta HTTP in uno qualsiasi dei tre modi seguenti:

  • Dalle associazioni di input e di output denominate. In questo modo, il trigger e le associazioni HTTP funzionano come qualsiasi altra associazione. L'esempio seguente imposta l'oggetto risposta usando un'associazione response denominata.

    context.bindings.response = { status: 201, body: "Insert succeeded." };
    
  • Dalle proprietà req e res sull'oggetto context. In questo modo per accedere ai dati HTTP dall'oggetto di contesto è possibile usare il modello convenzionale anziché il modello context.bindings.name completo. L'esempio seguente illustra come accedere agli oggetti req e res nell'oggetto context:

    // You can access your http request off the context ...
    if(context.req.body.emoji === ':pizza:') context.log('Yay!');
    // and also set your http response
    context.res = { status: 202, body: 'You successfully ordered more coffee!' }; 
    
  • Oppure chiamando context.done(). Un tipo speciale di associazione HTTP restituisce la risposta che viene passata al metodo context.done(). L'associazione di output HTTP seguente definisce un parametro di output $return:

    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
    

    Questa associazione di output prevede che l'utente dia la risposta quando chiama done(), come indicato di seguito:

     // Define a valid response object.
    res = { status: 201, body: "Insert succeeded." };
    context.done(null, res);   
    

Versione di Node e gestione dei pacchetti

La versione di Node è attualmente bloccata alla 6.5.0. Si sta analizzando la possibilità di aggiungere il supporto per altre versioni e renderle configurabili.

I passaggi seguenti consentono di includere i pacchetti nell'app per le funzioni:

  1. Passare a https://<function_app_name>.scm.azurewebsites.net.

  2. Fare clic su Debug Console > CMD (Console di debug > CMD).

  3. Passare a D:\home\site\wwwroot, quindi trascinare il file package.json nella cartella wwwroot nella metà superiore della pagina.
    È possibile caricare i file nell'app per le funzioni anche in altri modi. Per altre informazioni, vedere Come aggiornare i file delle app per le funzioni.

  4. Dopo aver caricato il file package.json, eseguire il comando npm install nella console di esecuzione remota Kudu.
    Questa azione scarica i pacchetti indicati nel file package.json e riavvia l'app per le funzioni.

Una volta che i pacchetti necessari sono installati, è possibile importarli nella funzione chiamando il metodo require('packagename'), come nell'esempio seguente:

// Import the underscore.js library
var _ = require('underscore');
var version = process.version; // version === 'v6.5.0'

module.exports = function(context) {
    // Using our imported underscore.js library
    var matched_names = _
        .where(context.bindings.myInput.names, {first: 'Carla'});

È necessario definire un file package.json nella directory principale dell'app per le funzioni. La definizione del file consente a tutte le funzioni dell'app di condividere gli stessi pacchetti memorizzati nella cache garantendo prestazioni migliori. In caso di conflitto di versione, è possibile risolverlo aggiungendo un file package.json nella cartella di una funzione specifica.

Variabili di ambiente

Per ottenere una variabile di ambiente o un valore di impostazione dell'app, usare process.envcome illustrato nell'esempio di codice seguente:

module.exports = function (context, myTimer) {
    var timeStamp = new Date().toISOString();

    context.log('Node.js timer trigger function ran!', timeStamp);   
    context.log(GetEnvironmentVariable("AzureWebJobsStorage"));
    context.log(GetEnvironmentVariable("WEBSITE_SITE_NAME"));

    context.done();
};

function GetEnvironmentVariable(name)
{
    return name + ": " + process.env[name];
}

Considerazioni per le funzioni JavaScript

Quando si usano le funzioni JavaScript, tenere presente le considerazioni nelle due sezioni che seguono.

Scegliere i piani di servizio app single core

Quando si crea un'app per le funzioni che usa il piano di servizio app, è consigliabile selezionare un piano single core anziché uno con più core. Oggi Funzioni esegue funzioni JavaScript in modo più efficiente in macchine virtuali single core e l'uso di macchine virtuali di dimensioni maggiori non produce i miglioramenti delle prestazioni previsti. Se necessario, è possibile scalare orizzontalmente manualmente aggiungendo altre istanze di macchine virtuali single core oppure abilitare la scalabilità automatica. Per altre informazioni, vedere Scalare il conteggio delle istanze manualmente o automaticamente.

Supporto TypeScript e CoffeeScript

Dal momento che non è ancora disponibile il supporto diretto per la compilazione automatica di TypeScript o CoffeeScript tramite il runtime, il supporto deve essere gestito all'esterno del runtime al momento della distribuzione.

Passaggi successivi

Per altre informazioni, vedere le seguenti risorse: