Migrar para a versão 4 do modelo de programação Node.js do Azure Functions
Este artigo discute as diferenças entre a versão 3 e a versão 4 do modelo de programação Node.js e como atualizar um aplicativo v3 existente. Se você quiser criar um novo aplicativo v4 em vez de atualizar um aplicativo v3 existente, confira o tutorial do Visual Studio Code (VS Code) ou do Azure Functions Core Tools. Este artigo usa alertas de "dicas" para destacar as ações concretas mais importantes que você deve tomar para atualizar seu aplicativo.
A versão 4 foi projetada para fornecer aos desenvolvedores Node.js os seguintes benefícios:
- Fornecer uma experiência familiar e intuitiva para desenvolvedores Node.js.
- Tornar a estrutura de arquivos flexível com suporte para personalização completa.
- Alternar para uma abordagem centrada em código para definir a configuração da função.
Considerações
- O modelo de programação Node.js não deve ser confundido com o runtime do Azure Functions:
- Modelo de programação: define como você cria seu código e é específico para JavaScript e TypeScript.
- Runtime: define o comportamento subjacente do Azure Functions e é compartilhado em todos os idiomas.
- A versão do modelo de programação está estritamente vinculada à versão do pacote npm
@azure/functions
. Ele tem controle de versão independentemente do runtime. O runtime e o modelo de programação usam o número 4 como sua versão principal mais recente, mas isso é uma coincidência. - Você não pode misturar os modelos de programação v3 e v4 no mesmo aplicativo de funções. Assim que você registra uma função v4 no aplicativo, todas as funções v3 registradas em arquivos function.json são ignoradas.
Requisitos
A versão 4 do modelo de programação Node.js requer as seguintes versões mínimas:
- Pacote npm v4.0.0
@azure/functions
- Node.js v18+
- Azure Functions Runtime v4.25+
- Azure Functions Core Tools v4.0.5382+ (se em execução localmente)
- Pacote npm v4.0.0
@azure/functions
- Node.js v18+
- TypeScript v4+
- Azure Functions Runtime v4.25+
- Azure Functions Core Tools v4.0.5382+ (se em execução localmente)
Incluir o pacote npm
Na v4, o pacote npm @azure/functions
contém o código-fonte primário que apoia o modelo de programação Node.js. Em versões anteriores, esse código era enviado diretamente no Azure e o pacote npm tinha apenas os tipos TypeScript. Agora você precisa incluir este pacote para aplicativos TypeScript e JavaScript. Você pode incluir o pacote para aplicativos v3 existentes, mas ele não é necessário.
Dica
Verifique se o pacote @azure/functions
está listado na seção dependencies
(não devDependencies
) do arquivo package.json. Você pode instalar a v4 usando o seguinte comando:
npm install @azure/functions
Definir o ponto de entrada do aplicativo
Na v4 do modelo de programação, você pode estruturar seu código como desejar. Os únicos arquivos necessários na raiz do aplicativo são host.json e package.json.
Caso contrário, defina a estrutura do arquivo definindo o campo main
no arquivo package.json. Você pode definir o campo main
para um único ou vários arquivos usando um padrão glob. A tabela a seguir mostra valores de exemplo para o campo main
:
Exemplo | Descrição |
---|---|
src/index.js |
Registrar funções de um único arquivo raiz. |
src/functions/*.js |
Registrar cada função de seu próprio arquivo. |
src/{index.js,functions/*.js} |
Uma combinação em que você registra cada função de seu próprio arquivo, mas ainda tem um arquivo raiz para código geral no nível do aplicativo. |
Exemplo | Descrição |
---|---|
dist/src/index.js |
Registrar funções de um único arquivo raiz. |
dist/src/functions/*.js |
Registrar cada função de seu próprio arquivo. |
dist/src/{index.js,functions/*.js} |
Uma combinação em que você registra cada função de seu próprio arquivo, mas ainda tem um arquivo raiz para código geral no nível do aplicativo. |
Dica
Defina um campo main
no arquivo package.json.
Alternar a ordem dos argumentos
A entrada do gatilho, em vez do contexto de invocação, é agora o primeiro argumento do manipulador de função. O contexto de invocação, agora o segundo argumento, foi simplificado na v4 e não é tão necessário quanto a entrada do gatilho. Você pode deixá-la desativada se não estiver usando.
Dica
Alterne a ordem dos argumentos. Por exemplo, se você estiver usando um gatilho HTTP, alterne (context, request)
para (request, context)
ou apenas (request)
se não estiver usando o contexto.
Definir sua função no código
Você não precisa mais criar e manter esses arquivos de configuração function.json separados. Agora você pode definir totalmente suas funções diretamente em seus arquivos TypeScript ou JavaScript. Além disso, muitas propriedades agora têm padrões para que você não precise especificá-las todas as vezes.
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,
});
Dica
Mova a configuração do arquivo function.json para o seu código. O tipo do gatilho corresponde a um método no objeto app
no novo modelo. Por exemplo, se você usar um tipo httpTrigger
em function.json, chame app.http()
em seu código para registrar a função. Se você usar timerTrigger
, chame app.timer()
.
Examinar o uso do contexto
Na v4, o objeto context
é simplificado para reduzir a duplicação e facilitar a gravação de testes de unidade. Por exemplo, simplificamos a entrada e a saída primárias para que sejam acessadas apenas como argumento e valor de retorno do seu manipulador de função.
Não é mais possível acessar a entrada e a saída primárias do objeto context
, mas ainda é necessário acessar as entradas e saídas secundárias do objeto context
. Para obter mais informações sobre entradas e saídas secundárias, confira o guia do desenvolvedor Node.js.
Obter a entrada primária como um argumento
A entrada primária também é chamada de gatilho e é a única entrada ou saída necessária. Você só pode ter um (e apenas um) gatilho.
A versão 4 dá suporte a apenas uma maneira de obter a entrada do gatilho como o primeiro argumento:
async function httpTrigger1(request, context) {
const onlyOption = request;
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
const onlyOption = request;
Dica
Verifique se você não está usando context.req
ou context.bindings
para obter a entrada.
Definir a saída primária como valor retornado
A versão 4 só dá suporte a uma maneira de definir a saída primária por meio do valor retornado:
return {
body: `Hello, ${name}!`
};
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
// ...
return {
body: `Hello, ${name}!`
};
}
Dica
Sempre retorne a saída em seu manipulador de função, em vez de defini-la com o objeto context
.
Registro de contexto
Na v4, os métodos de registro foram movidos para o objeto raiz context
, conforme mostrado no exemplo a seguir. Para obter mais informações sobre registro, veja o guia do desenvolvedor do Node.js.
context.log('This is an info log');
context.error('This is an error');
context.warn('This is an error');
Criar um contexto de teste
A versão 3 não dá suporte à criação de um contexto de invocação fora do runtime do Azure Functions, dificultando a criação de testes de unidade. A versão 4 permite que você crie uma instância do contexto de invocação, embora as informações durante os testes não sejam detalhadas, a menos que você a adicione por conta própria.
const testInvocationContext = new InvocationContext({
functionName: 'testFunctionName',
invocationId: 'testInvocationId'
});
Examinar o uso de tipos HTTP
Os tipos de solicitação e resposta HTTP agora são um subconjunto do fetch padrão. Eles não são mais exclusivos para o Azure Functions.
Os tipos usam o pacote undici
no Node.js. Esse pacote segue o fetch padrão e atualmente está sendo integrado ao núcleo do Node.js.
HttpRequest
Corpo. Você pode acessar o corpo usando um método específico para o tipo que deseja receber:
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();
Cabeçalho:
const header = request.headers.get('content-type');
Parâmetro de consulta:
const name = request.query.get('name');
HttpResponse
Status:
return { status: 200 };
Corpo:
Use a propriedade
body
para retornar a maioria dos tipos como umstring
ouBuffer
:return { body: "Hello, world!" };
Use a propriedade
jsonBody
para a maneira mais fácil de retornar uma resposta JSON:return { jsonBody: { hello: "world" } };
Cabeçalho. É possível definir o cabeçalho de duas maneiras, dependendo se você está usando a classe
HttpResponse
ou a interfaceHttpResponseInit
:const response = new HttpResponse(); response.headers.set('content-type', 'application/json'); return response;
return { headers: { 'content-type': 'application/json' } };
Dica
Atualize qualquer lógica usando os tipos de solicitação ou resposta HTTP para corresponder aos novos métodos.
Dica
Atualize qualquer lógica usando os tipos de solicitação ou resposta HTTP para corresponder aos novos métodos. Você deve obter erros de compilação do TypeScript para ajudar a identificar se está usando métodos antigos.
Solucionar problemas
Confira o Guia para solucionar problemas de Node.js.