Esercizio - Creare funzioni per l'app Funzioni di Azure

Completato

In questa unità si creano e si configurano le funzioni nell'app Funzioni di Azure per gli endpoint GET, POST, PUT e DELETE nell'app Node.js Express.

Aggiungi l'accesso ai dati alla funzione GET

Quando l'applicazione Azure Functions è stata creata nell'ultima unità, è stato creato il primo endpoint API. Questa funzione viene eseguita quando viene richiesto un HTTP GET in /vacations. È necessario aggiornare il codice boilerplate per chiamare il servizio dati per ottenere le ferie.

  1. Apri il file functions/src/functions/getVacations.ts.

  2. Apri il file server/routes/vacation.routes.ts in una finestra separata in modo da poter visualizzare entrambi i file affiancati.

  3. In getVacations.ts aggiungere l'istruzione di importo vacationService.

    import { vacationService } from '../services';
    
  4. In getVacations.ts modifica la funzione getVacations per chiamare 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. Potresti fermarti lì. Questo è l'unico codice che è necessario aggiungere alla funzione per ottenere le ferie. Tuttavia, è necessario fornire anche il codice per gestire gli errori e restituire un codice di stato. Aggiorna la funzione per usare il codice seguente.

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

Organizza le route Funzioni di Azure

Nel modello di programmazione v4 è possibile organizzare le route in diversi modi. È possibile lasciare la definizione di route con il gestore di route in un singolo file. Questa operazione è adatta per un'applicazione con un endpoint. Gli sviluppatori di Tailwind Traders sanno che questa applicazione crescerà con molte API che devono essere organizzate.

  1. Per avviare l'organizzazione, crea un nuovo file ./functions/src/index.ts per acquisire le definizioni di route.

  2. Aggiungi la dipendenza per l'app fornita dal pacchetto @azure/functions.

    import { app } from '@azure/functions';
    
  3. Aggiungi la dipendenza per la funzione getVacations dal file ./functions/getVacations.

    import { getVacations } from `./functions/getVacations`;
    
  4. Sposta la definizione di route da ./functions/getVacations al file index.ts. Aggiorna la matrice di proprietà metodo in GET.

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

Denominazione della funzione e del gestore

Il nome getVacations viene usato sia come primo parametro per app.http che come proprietà nel secondo parametro. Questo può generare confusione e potrebbe essere necessario definire regole di denominazione diverse nell'organizzazione o nel team, a seconda del modo in cui viene usato il nome.

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

  • Primo parametro: nome come stringa: Il valore per il primo parametro è il nome della funzione come verrà visualizzata nel portale di Azure. Tali nomi sono elencati in modo alfanumerico nel portale, pertanto è consigliabile usare una convenzione di denominazione che raggruppa funzioni simili per scopo, ad esempio vacationGet o per metodo, ad esempio getVacation. È anche possibile scegliere un caso diverso, ad esempio snake_case, kebab-case, or camelCase.
  • Secondo parametro - Funzione del gestore: Il valore per il secondo parametro è il nome del gestore della funzione durante l'importazione e l'uso nel codice. Questo nome deve essere descrittivo e corrispondere allo scopo della funzione. Può essere conforme alle convenzioni di denominazione già presenti per le funzioni nella base di codice e può essere applicato con i tipici strumenti di conformità del codice.

Creare le funzioni rimanenti

Esistono quattro endpoint nell'applicazione Node.js Express e si è appena creata la funzione per l'endpoint GET. Creare ora funzioni per gli endpoint di route rimanenti.

metodo Nome del trigger HTTP Itinerario
POST postVacation vacations
PUT updateVacation vacations/{id}
DELETE deleteVacation vacations/{id}

Anche se le route GET e POST sono le stesse. Le route PUT e DELETE usano un parametro per identificare le ferie da usare.

Creare la funzione HTTP POST

Creare la funzione POST che gestisce l'aggiunta di una vacanza.

  1. In Visual Studio Code apri il riquadro comandi con CTRL + MAIUSC +P, digita Azure Functions: Create Function e premi INVIO.

  2. Selezio Trigger HTTP come tipo e postVacation come nome.

  3. Aggiungi l'istruzione di importo vacationService al file.

    import { vacationService } from '../services';
    
  4. Sostituisci la funzione boilerplate postVacation con il codice seguente per l'accesso ai dati e la gestione degli errori.

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

    Per leggere i dati delle ferie in arrivo, usa il metodo request.json(). Questo metodo fornisce una promessa che viene risolta nei dati JSON nel corpo della richiesta. Usa quindi la parola chiave await per attendere la risoluzione della promessa. La sintassi as Vacation è un'asserzione di tipo che indica a TypeScript di considerare il risultato come oggetto Vacation.

    const vacation = await request.json() as Vacation;
    
  5. Sposta la definizione di route dal file postVacation al file index.ts. Aggiorna la matrice di proprietà metodo in POST.

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

Creare la funzione HTTP PUT

Creare la funzione PUT che gestisce l'aggiunta di una vacanza.

  1. In Visual Studio Code apri il riquadro comandi con CTRL + MAIUSC + P, digita Azure Functions: Create Function e premi INVIO.

  2. Seleziona Trigger HTTP come tipo e updateVacation come nome.

  3. Aggiungi l'istruzione di importo vacationService al file.

    import { vacationService } from '../services';
    
  4. Sostituisci la funzione boilerplate updateVacation con il codice seguente per l'accesso ai dati e la gestione degli errori.

    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 proprietà request.params.id viene usata per ottenere l'ID delle ferie dall'URL. Il metodo request.json() viene usato per ottenere i dati delle ferie dal corpo della richiesta. La sintassi as Vacation è un'asserzione di tipo che indica a TypeScript di considerare il risultato come oggetto Vacation.

  5. Sposta la definizione di route dal file putVacation al file index.ts. Aggiorna la matrice di proprietà metodo in PUT.

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

Creare la funzione HTTP DELETE

Creare la funzione DELETE che gestisce l'aggiunta di una vacanza.

  1. In Visual Studio Code apri il riquadro comandi con CTRL + MAIUSC + P, digita Azure Functions: Create Function e premi INVIO.

  2. Seleziona Trigger HTTP come tipo e deleteVacation come nome.

  3. Aggiungi l'importazione vacationService al file.

    import { vacationService } from '../services';
    
  4. Sostituisci la funzione boilerplate deleteVacation con il codice seguente per l'accesso ai dati e la gestione degli errori.

    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 proprietà request.params.id viene usata per ottenere l'ID delle ferie dall'URL.

  5. Sposta la definizione di route dal file deleteVacation al file index.ts. Aggiorna la matrice di proprietà metodo in DELETE.

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

Passare all'unità successiva per esaminare l'applicazione Funzioni di Azure creata.