Menu
CoddyTech

Intercettori

Fa parte della sezione TypeScript e NestJS del percorso Node.js di Coddy. Lezione 23 di 24.

Vuoi che ogni risposta indichi quanto tempo ci è voluto, senza modificare ogni gestore. Un interceptor avvolge il gestore: il codice prima di next.handle() viene eseguito prima, mentre il codice sul valore restituito da next.handle() viene eseguito dopo.

intercept(context: ExecutionContext, next: CallHandler) {
    console.log('before');
    return next.handle().pipe(
        tap(() => console.log('after')),
    );
}

next.handle() fornisce il risultato del gestore come osservabile RxJS, un valore che arriva in seguito. .pipe(tap(...)) esegue una funzione quando arriva il valore, prima che Nest lo invii; questo pipe non ha nulla a che fare con le pipe di validazione di Nest. Le guardie vengono eseguite prima di qualsiasi interceptor, quindi una richiesta rifiutata da una guardia non lo raggiunge mai. Restituisci l’osservabile con la pipe: Nest invia ciò che contiene. context.switchToHttp().getResponse() fornisce res, il cui setHeader aggiunge un’intestazione.

app.useGlobalInterceptors(...) applica un interceptor a ogni route; @UseInterceptors(...) a un solo controller.

challenge icon

Sfida

Facile

Run avvia di nuovo il tuo tracker, usando src/main.ts. I file separati per gli esercizi possono restare nell'albero; questo server non li avvia.

I client e il tuo sistema di monitoraggio vogliono sapere quanto tempo ha impiegato ogni richiesta. Aggiungi un'intestazione di risposta, X-Response-Time, a ogni risposta riuscita, senza modificare alcuna route.

  1. Apri src/common/response-time.interceptor.ts. Nel metodo intercept di ResponseTimeInterceptor, annota per prima cosa l'ora corrente con Date.now(). Il codice all'inizio di intercept viene eseguito prima del metodo della route.
  2. Ottieni res di Express con context.switchToHttp().getResponse().
  3. next.handle() esegue il metodo della route e restituisce il risultato come observable di RxJS: un valore che arriva in seguito. Continua a restituirlo, ma passalo attraverso tap, già importato da rxjs, usando il metodo .pipe() dell'observable. La funzione che passi a tap viene eseguita quando arriva il risultato, prima che Nest lo invii. In quella funzione, chiama res.setHeader per impostare X-Response-Time sul numero di millisecondi trascorsi da quando hai annotato l'ora, seguito da ms, come in 3ms. (.pipe() di RxJS non ha nulla a che fare con i pipe di convalida del capitolo 3. Aggiunge un passaggio alla catena dell'observable.)
  4. In src/main.ts, registra l'interceptor per l'intera app con app.useGlobalInterceptors(...), passando una nuova istanza di ResponseTimeInterceptor, accanto al pipe e al filtro.
  5. I corpi delle risposte non devono cambiare. GET /tasks continua a restituire { "items": [...], "page": 1, "total": 3, "pages": 2 }.

Prova: invia GET /tasks e apri la scheda Headers della risposta. Vedrai X-Response-Time con un valore come 0ms o 2ms. Anche GET /stats lo include, così come una richiesta POST con { "title": "Buy milk" } inviata con l'intestazione x-api-key: tasks-key-123. Poi invia quella POST senza la chiave: 403, e nessun X-Response-Time. Nest esegue le guardie prima degli interceptor, quindi la guardia ha rifiutato la richiesta prima che l'interceptor si avviasse. Anche un errore generato all'interno di una route esclude l'intestazione, perché tap viene eseguito solo quando arriva un risultato.

Provalo tu

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, tap } from 'rxjs';

@Injectable()
export class ResponseTimeInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
        // Registra l'ora, lascia eseguire l'handler, poi imposta X-Response-Time.
        return next.handle();
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di TypeScript e NestJS

Esercitati da solo: Playground Express