Exercício – Criar funções para o aplicativo Azure Functions

Concluído

Nesta unidade, você cria e configura funções no aplicativo Azure Functions para os pontos de extremidade GET, POST, PUT, e DELETE no aplicativo Node.js Express.

Adicionar acesso a dados à função GET

Você criou o primeiro ponto de extremidade de API quando criou o aplicativo do Azure Functions na última unidade. Essa função é executada quando um HTTP GET é solicitado em /vacations. Você precisa atualizar o código clichê para chamar o serviço de dados para obter as férias.

  1. Abra o arquivo functions/src/functions/getVacations.ts.

  2. Abra o arquivo server/routes/vacation.routes.ts em uma janela separada para que você possa ver os dois arquivos lado a lado.

  3. Em getVacations.ts, adicione a instrução de importação vacationService.

    import { vacationService } from '../services';
    
  4. Em getVacations.ts, edite a função getVacations para chamar o 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. Você poderia parar por aí. Esse é o único código que você precisa adicionar à função para obter as férias. No entanto, você também deve fornecer código para lidar com erros e retornar um código de status. Atualize a função para usar o código a seguir.

     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'
           }
         };
       }
     };
    

Organizar as rotas do Azure Functions

No modelo de programação v4, você pode organizar suas rotas de várias maneiras. Você pode deixar a definição de rota com o manipulador de rotas em um único arquivo. Isso é bom para um aplicativo com um ponto de extremidade. Como desenvolvedor da Tailwind Traders, você sabe que esse aplicativo aumentará para muitas APIs que precisam ser organizadas.

  1. Para iniciar essa organização, crie um novo arquivo ./functions/src/index.ts para capturar as definições de rota.

  2. Adicione a dependência para o aplicativo fornecido a partir do pacote @azure/functions.

    import { app } from '@azure/functions';
    
  3. Adicione a dependência da função getVacations do arquivo ./functions/getVacations.

    import { getVacations } from `./functions/getVacations`;
    
  4. Mova a definição de rota de ./functions/getVacations para o arquivo index.ts. Atualize a matriz de propriedades do método para GET.

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

Nomear a função e o manipulador

O nome getVacations é usado como o primeiro parâmetro para app.http e como uma propriedade no segundo parâmetro. Isso pode ser confuso e talvez você queira ter regras de nomenclatura diferentes em sua organização ou equipe, dependendo de como o nome é usado.

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

  • Primeiro parâmetro – nome como cadeia de caracteres: O valor do primeiro parâmetro é o nome da função, pois ela será exibida no portal do Azure. Esses nomes são listados alfanumericamente no portal, portanto, talvez você queira usar uma convenção de nomenclatura que agrupa funções semelhantes por finalidade, como vacationGet ou por método, como getVacation. Você também pode escolher uma opção de maiúsculas e minúsculas diferente, como snake_case, kebab-case ou camelCase.
  • Segundo parâmetro – função de manipulador: O valor do segundo parâmetro é o nome do manipulador de funções, pois ele é importado e usado no código. Esse nome deve ser descritivo e corresponder à finalidade da função. Ele pode estar em conformidade com as convenções de nomenclatura que você já tem para funções em sua base de código e pode ser imposto com ferramentas típicas de conformidade de código.

Criar as funções restantes

Há quatro pontos de extremidade no aplicativo Node.js Express e você acabou de criar a função para o ponto de extremidade GET. Agora, crie funções para os pontos de extremidade de rota restantes.

Método Nome do gatilho HTTP Rota
POST postVacation vacations
PUT updateVacation vacations/{id}
DELETE deleteVacation vacations/{id}

Embora as rotas GET e POST sejam as mesmas. As rotas PUT e DELETE usam um parâmetro para identificar quais férias usar.

Criar a Função HTTP POST

Crie a função POST que cuida da adição das férias.

  1. No Visual Studio Code, abra a paleta de comandos com Ctrl + Shift +P, digite Azure Functions: Create Function e pressione Enter.

  2. Selecione Gatilho HTTP como o tipo e postVacation como o nome.

  3. Adicione a instrução de importação vacationService ao arquivo.

    import { vacationService } from '../services';
    
  4. Substitua a função clichê postVacation pelo código a seguir para acesso a dados e tratamento de erros.

    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 ler os dados de férias de entrada, use o método request.json(). Este método retorna uma promessa que é resolvida para os dados JSON no corpo da solicitação. Em seguida, use a palavra-chave await para aguardar a promessa ser resolvida. A sintaxe as Vacation é uma declaração de tipo que diz ao TypeScript para tratar o resultado como um objeto Vacation.

    const vacation = await request.json() as Vacation;
    
  5. Mova a definição de rota do arquivo postVacation para o arquivo index.ts. Atualize a matriz de propriedades do método para POST.

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

Criar a Função HTTP PUT

Crie a função PUT que cuida da adição das férias.

  1. No Visual Studio Code, abra a paleta de comandos com Ctrl + Shift + P, digite Azure Functions: Create Function e pressione Enter.

  2. Selecione Gatilho HTTP como o tipo e updateVacation como o nome.

  3. Adicione a instrução de importação vacationService ao arquivo.

    import { vacationService } from '../services';
    
  4. Substitua a função clichê updateVacation pelo código a seguir para acesso a dados e tratamento de erros.

    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'
          }
        };
      }
    };
    

    A propriedade request.params.id é usada para obter a ID de férias da URL. O método request.json() é usado para obter os dados de férias do corpo da solicitação. A sintaxe as Vacation é uma declaração de tipo que diz ao TypeScript para tratar o resultado como um objeto Vacation.

  5. Mova a definição de rota do arquivo putVacation para o arquivo index.ts. Atualize a matriz de propriedades do método para PUT.

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

Criar a Função HTTP DELETE

Crie a função DELETE que cuida da adição das férias.

  1. No Visual Studio Code, abra a paleta de comandos com Ctrl + Shift + P, digite Azure Functions: Create Function e pressione Enter.

  2. Selecione Gatilho HTTP como o tipo e deleteVacation como o nome.

  3. Adicione a importação vacationService ao arquivo.

    import { vacationService } from '../services';
    
  4. Substitua a função clichê deleteVacation pelo código a seguir para acesso a dados e tratamento de erros.

    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'
          }
        };
      }
    };
    

    A propriedade request.params.id é usada para obter a ID de férias da URL.

  5. Mova a definição de rota do arquivo deleteVacation para o arquivo index.ts. Atualize a matriz de propriedades do método para DELETE.

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

Vá para a próxima unidade para examinar o aplicativo Azure Functions que você criou.