nestjs中的中间件顺序

在NestJS中,中间件(Middleware)、管道(Pipes)、拦截器(Interceptors)和守卫(Guards)是四种常用的处理请求的机制。它们的执行顺序是有明确规定的,这对于理解和设计NestJS应用的请求处理流程非常重要。

执行顺序概述

  1. 中间件(Middleware)
  2. 守卫(Guards)
  3. 拦截器(Interceptors)(Before handling the request)
  4. 管道(Pipes)
  5. 拦截器(Interceptors)(After handling the request)

详细执行顺序

  1. 中间件(Middleware)

    • 中间件在路由处理之前执行,可以用于处理请求的预处理工作,比如日志记录、请求解析、认证等。
    • 中间件只能在模块级别或应用级别定义,不能在控制器或方法级别定义。
    • 中间件在请求生命周期的最早阶段执行。
  2. 守卫(Guards)

    • 守卫用于实现基于角色的访问控制和认证逻辑。
    • 守卫在每个请求之前执行,决定是否允许请求继续。
    • 守卫可以在模块、控制器或方法级别定义。
  3. 拦截器(Interceptors)(Before handling the request):

    • 拦截器在请求处理前后都可以执行。
    • 在处理请求前,拦截器可以对请求进行预处理,比如修改请求对象或添加额外的逻辑。
    • 拦截器可以在模块、控制器或方法级别定义。
  4. 管道(Pipes)

    • 管道用于验证和转换请求数据。
    • 管道在控制器方法处理请求之前执行,确保请求数据的有效性和格式。
    • 管道可以在控制器参数、方法或控制器级别定义。
  5. 拦截器(Interceptors)(After handling the request):

    • 拦截器在处理完请求之后,可以对响应进行后处理,比如修改响应对象或添加日志记录。
    • 这部分拦截器在控制器方法执行完毕后执行。

示例代码

为了更好地理解执行顺序,下面是一个示例代码,展示了如何在NestJS中定义和使用中间件、守卫、拦截器和管道。

中间件

import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () => void) {
    console.log('Request...');
    next();
  }
}

守卫

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

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    console.log('Guard...');
    return true; // or some authentication logic
  }
}

拦截器

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

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');
    return next
      .handle()
      .pipe(
        tap(() => console.log('After...')),
      );
  }
}

管道

import {
  Injectable,
  PipeTransform,
  ArgumentMetadata,
  BadRequestException,
} from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    console.log('Pipe...');
    if (!value) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}

应用示例

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthGuard,
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('*');
  }
}

在这个示例中:

  1. LoggerMiddleware 会首先执行,记录请求信息。
  2. AuthGuard 会接着执行,进行认证和授权检查。
  3. LoggingInterceptor 会在请求处理前执行Before...逻辑。
  4. ValidationPipe 会在控制器方法处理请求之前验证和转换请求数据。
  5. LoggingInterceptor 会在请求处理后执行After...逻辑。

通过这种方式,你可以充分利用NestJS的中间件、守卫、拦截器和管道来构建灵活和可维护的请求处理流程。

posted @ 2024-08-11 16:08  jialiangzai  阅读(176)  评论(0)    收藏  举报