Supongamos que tenemos una función que queremos que se ejecute no solo cuando se llegue a esa ruta sino también cuando se cumplan determinadas condiciones. El filtro que protege a la funcion de ejecutarse o no según si estas reglas se cumplen se llama Guard. Para crearlo, también lo hacemos a través de la terminal.

nest generate guard rutaDondeQueremosQueSeCree

Una vez que se crea nos creará el archivo y su respectivo fichero de testing. Veamos el código

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}

Context

Como habrás visto en el código, se define un elemento context con el valor ExecutionContext. El ExecutionContext tiene acceso a todo el contexto de ejecución de la aplicación, por lo que se nos hace mas facil poder definir las condiciones de la guard.

Dentro de la función canActivate va toda la lógica del guard.

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest() as Request;
    console.log(request.url);
    return true;
  }
}

Como se ejecuta? Lo llamamos con un decorador llamado UseGuard en el controlador

  @Get('greet')
  @UseGuard(CustomGuard)
  greet(@Query(ValidategreetPipe) query: { name: string; age: number }) {
    return `Hello ${query.name}, you are ${query.age} years old`;
  }

Los guards son muy utiles para evitar ejecuciones basadas en los headers, por ejemplo que el controlador no ejecute la funcion asignada a la ruta si no está el header de administrador enviado también en la petición. Además, lo bueno de los guards en este caso es que los podes repetir en todas las rutas que pidas autorización.