Ejercicio: Creación de funciones para una aplicación de Azure Functions

Completado

En esta unidad, creará y configurará funciones en la aplicación de Azure Functions para los puntos de conexión GET, POST, PUT y DELETE en la aplicación de Node.js Express.

Adición de acceso a datos a la función GET

Creó el primer punto de conexión de API cuando creó la aplicación de Azure Functions en la última unidad. Esta función se ejecuta cuando se solicita un HTTP GET en /vacations. Debe actualizar el código reutilizable para llamar al servicio de datos para obtener las vacaciones.

  1. Abra el archivo functions/src/functions/getVacations.ts.

  2. Abra el archivo server/routes/vacation.routes.ts en una ventana independiente para que pueda ver ambos archivos en paralelo.

  3. En getVacations.ts, agregue la instrucción de importación vacationService.

    import { vacationService } from '../services';
    
  4. En getVacations.ts, edite la función getVacations para llamar a vacationService.

     export async function getVacations(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
         context.log(`Http function processed request for url "${request.url}"`);
         return { jsonBody: vacationService.getVacations() }; // Data access logic within the return object
     };
    
  5. Podría dejarlo ahí. Ese es el único código que necesita para agregar a la función para obtener las vacaciones. Sin embargo, también debe proporcionar código para controlar los errores y devolver un código de estado. Actualice la función para usar el siguiente código.

     export async function getVacations(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
       context.log(`Http function processed request for url "${request.url}"`);
    
       try {
         const vacations = vacationService.getVacations();  // Data access logic
    
         if (vacations) {
           return {
             status: 200,
             jsonBody: vacations
           };
         } else {
           return {
             status: 404,
             jsonBody: {
               error: 'No vacations found'
             }
           };
         }      
       } catch (error: unknown) {
         const err = error as Error;
         context.error(`Error listing vacations: ${err.message}`);
    
         return {
           status: 500,
           jsonBody: {
             error: 'Failed to list vacations'
           }
         };
       }
     };
    

Organización de las rutas de Azure Functions

En el modelo de programación v4, puede organizar las rutas de varias maneras. Puede dejar la definición de ruta con el controlador de ruta en un único archivo. Esto es adecuado para una aplicación con un punto de conexión. Como desarrollador de Tailwind Traders, sabe que esta aplicación aumentará a muchas API que deben organizarse.

  1. Para iniciar esa organización, cree un nuevo archivo ./functions/src/index.ts para capturar las definiciones de ruta.

  2. Agregue la dependencia de la aplicación proporcionada desde el paquete @azure/functions.

    import { app } from '@azure/functions';
    
  3. Agregue la dependencia de la función getVacations del archivo ./functions/getVacations.

    import { getVacations } from `./functions/getVacations`;
    
  4. Mueva la definición de ruta de ./functions/getVacations al archivo index.ts. Actualice la matriz de propiedades del método a GET.

    app.http('getVacations', {
        methods: ['GET'],
        route: 'vacations',
        authLevel: 'anonymous',
        handler: getVacations
    });
    

Nomenclatura de la función y el controlador

El nombre getVacations se usa como primer parámetro para app.http y como propiedad en el segundo parámetro. Esto puede resultar confuso y es posible que desee reglas de nomenclatura diferentes en su organización o equipo, en función de cómo se use el nombre.

Screenshot of the http definition with the first parameter numbered as one, and the second parameter's handler property numbered as two.

  • Primer parámetro: nombre como cadena: El valor del primer parámetro es el nombre de la función tal como aparecerá en Azure Portal. Esos nombres se enumeran alfanuméricamente en el portal, por lo que puede que quiera usar una convención de nomenclatura que agrupe funciones similares de forma conjunta, como vacationGet o por método, como getVacation. También puede elegir otro caso, como snake_case, kebab-case o camelCase.
  • Segundo parámetro: función de controlador: El valor del segundo parámetro es el nombre del controlador de funciones a medida que se importa y se usa en el código. Este nombre debe ser descriptivo y coincidir con el propósito de la función. Puede cumplir con las convenciones de nomenclatura que ya tiene para las funciones de la base de código y se pueden aplicar con herramientas de conformidad de código típicas.

Creación de las funciones restantes

Hay cuatro puntos de conexión en la aplicación de Node.js Express y acaba de crear la función para el punto de conexión GET. Ahora, cree funciones para los puntos de conexión de ruta restantes.

Método Nombre del desencadenador HTTP Ruta
POST postVacation vacations
PUT updateVacation vacations/{id}
DELETE deleteVacation vacations/{id}

Aunque las rutas GET y POST son las mismas. Las rutas PUT y DELETE usan un parámetro para identificar qué vacaciones se van a usar.

Creación de la función HTTP POST

Cree la función POST que se encarga de agregar vacaciones.

  1. En Visual Studio Code, abra la paleta de comandos con Ctrl + Mayús +P y escriba Azure Functions: Create Function y presione Entrar.

  2. Seleccione Desencadenador HTTP como tipo y postVacation como nombre.

  3. Agregue la instrucción de importación vacationService al archivo.

    import { vacationService } from '../services';
    
  4. Reemplace la función reutilizable postVacation por el siguiente código para el acceso a datos y el control de errores.

    export async function postVacation(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`HTTP function processed request for URL: "${request.url}"`);
    
        try {
            const vacation = await request.json() as Vacation;
    
            // Validate the vacation object
            if (!vacation || typeof vacation !== 'object' || !vacation.name || !vacation.description) {
                return {
                    status: 400,
                    jsonBody: { 
                        error: 'Invalid or missing vacation data.' 
                    }
                };
            }
    
            // Data access logic
            const newVacation = vacationService.addVacation(vacation); 
    
            // Successfully added the vacation
            return {
                status: 201,
                jsonBody: newVacation
            };
        } catch (error: unknown) {
            const err = error as Error;
            context.error(`Error create vacation: ${err.message}`);
    
            return {
                status: 500,
                jsonBody: {
                    error: 'Failed to create vacation'
                }
            };
        }
    }
    

    Para leer los datos de vacaciones entrantes, use el método request.json(). Este método devuelve una promesa que se resuelve en los datos JSON del cuerpo de la solicitud. A continuación, use la palabra clave await para esperar a que se resuelva la promesa. La sintaxis as Vacation es una aserción de tipo que indica a TypeScript que trate el resultado como un objeto Vacation.

    const vacation = await request.json() as Vacation;
    
  5. Mueva la definición de ruta del archivo postVacation al archivo index.ts. Actualice la matriz de propiedades del método a POST.

    app.http('post-vacation', {
        methods: ['POST'],
        route: 'vacations',
        authLevel: 'anonymous',
        handler: postVacation
    });
    

Creación de la función HTTP PUT

Cree la función PUT que se encarga de agregar vacaciones.

  1. En Visual Studio Code, abra la paleta de comandos con Ctrl + Mayús + P y escriba Azure Functions: Create Function y presione Entrar.

  2. Seleccione Desencadenador HTTP como tipo y updateVacation como nombre.

  3. Agregue la instrucción de importación vacationService al archivo.

    import { vacationService } from '../services';
    
  4. Reemplace la función reutilizable updateVacation por el siguiente código para el acceso a datos y el control de errores.

    export async function updateVacation(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
      try {
        const id = request.params.id;
        const { name, description } = await request.json() as Vacation;
    
        // Data access logic
        const updatedVacation = vacationService.updateVacation({ id, name, description });
    
        if (updatedVacation !== undefined) {
          return {
            status: 200,
            jsonBody: {
              updatedVacation
            }
          };
        } else {
          return {
            status: 404,
            jsonBody: {
              error: `Vacation with ID ${id} not found`
            }
          };
        }
      } catch (error: unknown) {
        const err = error as Error;
        context.error(`Error updating vacation: ${err.message}`);
    
        return {
          status: 500,
          jsonBody: {
            error: 'Failed to update vacation'
          }
        };
      }
    };
    

    La propiedad request.params.id se usa para obtener el identificador de vacaciones de la dirección URL. El método request.json() se usa para obtener los datos de vacaciones del cuerpo de la solicitud. La sintaxis as Vacation es una aserción de tipo que indica a TypeScript que trate el resultado como un objeto Vacation.

  5. Mueva la definición de ruta del archivo putVacation al archivo index.ts. Actualice la matriz de propiedades del método a PUT.

    app.http('updateVacation', {
        methods: ['PUT'],
        route: 'vacations/{id}',
        authLevel: 'anonymous',
        handler: updateVacation
    });
    

Creación de la función HTTP DELETE

Cree la función DELETE que se encarga de agregar vacaciones.

  1. En Visual Studio Code, abra la paleta de comandos con Ctrl + Mayús + P y escriba Azure Functions: Create Function y presione Entrar.

  2. Seleccione Desencadenador HTTP como tipo y deleteVacation como nombre.

  3. Agregue la importación vacationService al archivo.

    import { vacationService } from '../services';
    
  4. Reemplace la función reutilizable deleteVacation por el siguiente código para el acceso a datos y el control de errores.

    export async function deleteVacation(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
      context.log(`Http function processed request for url "${request.url}"`);
    
      try {
    
        const id = request.params.id;
    
        if (!id) {
          return {
            status: 400,
            jsonBody: {
              error: 'ID parameter is required'
            }
          };
        }
    
        const deletedVacation = vacationService.deleteVacation(id);
    
        if (deletedVacation) {
          return {
            status: 204,
            jsonBody: {
              deleteVacation
            }
          };
        } else {
          return {
            status: 404,
            jsonBody: {
              error: `Vacation with ID ${id} not found`
            }
          };
        }
      } catch (error: unknown) {
        const err = error as Error;
        context.error(`Error deleting vacation: ${err.message}`);
    
        return {
          status: 500,
          jsonBody: {
            error: 'Failed to delete vacation'
          }
        };
      }
    };
    

    La propiedad request.params.id se usa para obtener el identificador de vacaciones de la dirección URL.

  5. Mueva la definición de ruta del archivo deleteVacation al archivo index.ts. Actualice la matriz de propiedades del método a DELETE.

    app.http('deleteVacation', {
        methods: ['DELETE'],
        route: 'vacations/{id}',
        authLevel: 'anonymous',
        handler: deleteVacation
    });
    

Vaya a la unidad siguiente para revisar la aplicación de Azure Functions que ha creado.