Migración a la versión 4 del modelo de programación de Node.js para Azure Functions
En este artículo se describen las diferencias entre la versión 3 y la versión 4 del modelo de programación de Node.js y cómo actualizar una aplicación existente de la versión 3. Si quiere crear una aplicación nueva de la versión 4 en lugar de actualizar una aplicación existente de la versión 3, consulte el tutorial para Visual Studio Code (VS Code) o Azure Functions Core Tools. En este artículo se usan alertas de “sugerencias” para resaltar las acciones concretas más importantes que debe realizar para actualizar la aplicación.
La versión 4 está diseñada para proporcionar a los desarrolladores Node.js las siguientes ventajas:
- Proporcionar una experiencia familiar e intuitiva a los desarrolladores de Node.js.
- Hacer que la estructura de los archivos sea flexible con compatibilidad con la personalización completa.
- Cambiar a un enfoque centrado en el código para definir la configuración de funciones.
Consideraciones
- El modelo de programación de Node.js no debe confundirse con el runtime de Azure Functions:
- Modelo de programación: define cómo crea el código y es específico de JavaScript y TypeScript.
- Runtime: define el comportamiento subyacente de Azure Functions y se comparte en todos los lenguajes.
- La versión del modelo de programación está estrictamente vinculada a la versión del paquete npm
@azure/functions
. Se versiona independientemente del runtime. Tanto el runtime como el modelo de programación usan el número 4 como versión principal más reciente, pero es casualidad. - No puede mezclar los modelos de programación de las versiones 3 y 4 en la misma aplicación de funciones. En cuanto registre una función de la versión 4 en la aplicación, se omiten las funciones de la versión 3 registradas en los archivos function.json.
Requisitos
La versión 4 del modelo de programación de Node.js requiere las siguientes versiones mínimas:
- Paquete npm
@azure/functions
v4.0.0 - Node.js: v18 o posteriores
- Azure Functions Runtime v4.25 o posteriores
- Azure Functions Core Tools v4.0.5382 o posteriores (si se ejecuta localmente)
- Paquete npm
@azure/functions
v4.0.0 - Node.js: v18 o posteriores
- TypeScript: v4 o posteriores
- Azure Functions Runtime v4.25 o posteriores
- Azure Functions Core Tools v4.0.5382 o posteriores (si se ejecuta localmente)
Inclusión del paquete npm
En la versión 4, el paquete npm @azure/functions
contiene el código fuente principal que respalda el modelo de programación de Node.js. En versiones anteriores, ese código se entregaba directamente en Azure y el paquete npm solo tenía los tipos de TypeScript. Ahora debe incluir este paquete para las aplicaciones de TypeScript y JavaScript. Puede incluir el paquete para las aplicaciones existentes de la versión 3, pero no es necesario.
Sugerencia
Asegúrese de que el paquete @azure/functions
aparezca en la sección dependencies
(no devDependencies
) del archivo package.json. Puede instalar la versión 4 mediante el siguiente comando:
npm install @azure/functions
Definición del punto de entrada de la aplicación
En la versión 4 del modelo de programación, puede estructurar el código de la forma que desee. Los únicos archivos que necesita en la raíz de la aplicación son host.json y package.json.
De lo contrario, debe definir la estructura de archivos; para ello, debe establecer el campo main
en el archivo package.json. Puede establecer el campo main
en un único archivo o en varios archivos mediante un patrón global. En la tabla siguiente se muestran valores de ejemplo para el main
campo:
Ejemplo | Descripción |
---|---|
src/index.js |
Registrar funciones desde un único archivo raíz. |
src/functions/*.js |
Registre cada función desde su propio archivo. |
src/{index.js,functions/*.js} |
Combinación en la que se registra cada función desde su propio archivo, pero todavía tiene un archivo raíz para el código general de nivel de aplicación. |
Ejemplo | Descripción |
---|---|
dist/src/index.js |
Registrar funciones desde un único archivo raíz. |
dist/src/functions/*.js |
Registre cada función desde su propio archivo. |
dist/src/{index.js,functions/*.js} |
Combinación en la que se registra cada función desde su propio archivo, pero todavía tiene un archivo raíz para el código general de nivel de aplicación. |
Sugerencia
Asegúrese de definir un campo main
en el archivo package.json.
Cambio del orden de los argumentos
La entrada del desencadenador, en lugar del contexto de invocación, ahora es el primer argumento para el controlador de funciones. El contexto de invocación, que ahora es el segundo argumento, se ha simplificado en la versión 4 y no es tan necesario como la entrada del desencadenador. Puede dejarlo desactivado si no lo está usando.
Sugerencia
Cambie el orden de los argumentos. Por ejemplo, si usa un desencadenador HTTP, cambie (context, request)
a (request, context)
o simplemente (request)
si no usa el contexto.
Definición de la función en el código
Ya no tiene que crear y mantener esos archivos de configuración function.json independientes. Ahora puede definir completamente las funciones directamente en los archivos TypeScript o JavaScript. Además, muchas propiedades ahora tienen valores predeterminados para que no tenga que especificarlas cada vez.
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,
});
Sugerencia
Mueva la configuración del archivo function.json al código. El tipo del desencadenador se corresponde con un método en el objeto app
del nuevo modelo. Por ejemplo, si usa un tipo httpTrigger
en function.json, llame a app.http()
en el código para registrar la función. Si usa timerTrigger
, llame a app.timer()
.
Revisión del uso del contexto
En la versión 4, el objeto context
se simplifica para reducir la duplicación y facilitar la escritura de pruebas unitarias. Por ejemplo, hemos simplificado la entrada y la salida principales para que solo se acceda a ellas como argumento y valor devuelto del controlador de funciones.
Ya no puede acceder a la entrada y salida principales en el objeto context
, pero todavía debe acceder a las entradas y salidas secundarias en el objeto context
. Para obtener más información sobre las entradas y salidas secundarias, consulte la guía para desarrolladores de Node.js.
Obtención de la entrada principal como argumento
La entrada principal también se denomina desencadenador y es la única entrada o salida necesaria. Debe tener solo un desencadenador.
La versión 4 solo admite una manera de obtener la entrada del desencadenador, como primer argumento:
async function httpTrigger1(request, context) {
const onlyOption = request;
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
const onlyOption = request;
Sugerencia
Asegúrese de que no está usando context.req
o context.bindings
para obtener la entrada.
Definición de la salida principal como valor devuelto
La versión 4 solo admite una forma de definir la salida principal, a través del valor devuelto:
return {
body: `Hello, ${name}!`
};
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
// ...
return {
body: `Hello, ${name}!`
};
}
Sugerencia
Asegúrese de que siempre devuelve la salida en el controlador de funciones, en lugar de establecerla con el objeto context
.
Registro de contexto
En la versión 4, los métodos de registro se movieron al objeto raíz context
, como se muestra en el ejemplo siguiente. Para obtener más información sobre el registro, consulte la guía para desarrolladores de Node.js.
context.log('This is an info log');
context.error('This is an error');
context.warn('This is an error');
Creación de un contexto de prueba
La versión 3 no admite la creación de un contexto de invocación fuera del entorno de ejecución de Azure Functions, por lo que la creación de pruebas unitarias puede ser difícil. La versión 4 permite crear una instancia del contexto de invocación, aunque la información durante las pruebas no se detalla a menos que la agregue usted mismo.
const testInvocationContext = new InvocationContext({
functionName: 'testFunctionName',
invocationId: 'testInvocationId'
});
Revisión del uso de tipos HTTP
Los tipos de solicitud y respuesta HTTP ahora son un subconjunto del estándar de captura. Ya no son exclusivos de Azure Functions.
Los tipos usan el paquete undici
en Node.js. Este paquete sigue el estándar de captura y actualmente se está integrando en el núcleo de Node.js.
HttpRequest
Cuerpo. Puede acceder al cuerpo mediante un método específico del tipo que desea recibir:
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();
Encabezado:
const header = request.headers.get('content-type');
Parámetro de consulta:
const name = request.query.get('name');
HttpResponse
Estado:
return { status: 200 };
Cuerpo:
Use la
body
propiedad para devolver la mayoría de los tipos como ostring
Buffer
:return { body: "Hello, world!" };
Use la
jsonBody
propiedad para obtener la manera más sencilla de devolver una respuesta JSON:return { jsonBody: { hello: "world" } };
Encabezado. Puede establecer el encabezado de dos maneras, en función de si usa la clase
HttpResponse
o la interfazHttpResponseInit
:const response = new HttpResponse(); response.headers.set('content-type', 'application/json'); return response;
return { headers: { 'content-type': 'application/json' } };
Sugerencia
Actualice cualquier lógica mediante los tipos de solicitud o respuesta HTTP para que coincidan con los nuevos métodos.
Sugerencia
Actualice cualquier lógica mediante los tipos de solicitud o respuesta HTTP para que coincidan con los nuevos métodos. Debe obtener errores de compilación de TypeScript para ayudarle a identificar si usa métodos antiguos.
Solución de problemas
Consulte la guía de solución de problemas de Node.js.