前语

近年TS的兴起,Nest可谓乘风顺势,快速崛起,成为咱们前端的技术必了解之一,这不我也在赶上年代的马车,快速浅浅学习一波。而前面Nest探求(一)咱们已经说过了Nest的项目创立、文件架构以及swagger文档,然后咱们又在Nest探求(二)中,讲述了TypeOrm相关数据库的简略操作,后续咱们还会细讲。

今日咱们就来说说更为复杂的中间件、过滤器、管道、护卫。

中间件

介绍

中间件是在路由处理程序之前调用目标,在Nest中,中间件函数能够访问恳求和呼应目标,以及使用程序恳求呼应周期中的next()中间件函数。next()中间件函数一般由名为next的变量表示。

实践上等价于express中间件,有兴趣的同学能够了解了解 express和koa,然后再引用这篇文章里边的评论,这句话归纳的很好:通俗的讲,中间件便是一段管道,加入一个新的中间件便是把新的一段管道塞进原有大管道中,这段新的管道能够在自己内部对流过的数据、恳求等等信息流进行恣意操作(包含歹意的)。

中间件函数能够履行以下使命:

  • 履行任何代码。
  • 对恳求和呼应目标进行更改。
  • 完毕恳求-呼应周期。
  • 调用仓库中的下一个中间件函数。
  • 如果当前的中间件函数没有完毕恳求-呼应周期, 它有必要调用next()将操控传递给下一个中间件函数。不然, 恳求将被挂起。

示例

创立一个中间件类并完成RequestLoggerMiddleware接口,然后在use()办法中编写中间件逻辑。

import { Injectable, NestMiddleware } from "@nestjs/common"
import { NextFunction, Request, Response } from "express";
@Injectable()
export class RequestLoggerMiddleware implements NestMiddleware {
 use(req: Request, res: Response, next: NextFunction) {
  try {
   const { user_id = '', user_name = '', referer = '' } = req.headers
   console.log(`接口恳求记载 {user_id: ${user_id}, user_name: ${decodeURI(user_name as string)
    }, ip: ${req.ip}, referer: ${referer}, method: ${req.method}, url: ${req.originalUrl}, body: ${JSON.stringify(req.body)}, res: ${res.statusCode}}`)
  } catch (e) {
    console.log(`接口恳求记载报错, ${e.stack}`)
  }
    next()
 }
}

在模块中注册中间件: 在需求运用中间件的模块中将中间件添加到providers数组中,并运用forRoutes()办法指定要使用中间件的路由。

typescriptCopy code
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { RequestLoggerMiddleware } from './logger.middleware';
@Module({})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(RequestLoggerMiddleware)
      .forRoutes('*');
  }
}

过滤器

介绍

过滤器是在路由处理程序之前或之后履行的函数。它们依据装修器的类型在相应的机遇进行履行,比方@UseFilters()装修器能够用于类和办法。

过滤器能够履行以下使命:

  • 操控器办法履行前后进行预处理或后处理。
  • 替换操控器办法的反常。
  • 反常转化为可视化的反常呼应。
  • 改变操控器办法返回的呼应目标。
  • 对恳求和呼应目标进行更改。

示例

创立一个过滤器类并运用@Catch()装修器来指定要捕获的反常类型,然后完成catch()办法来处理反常。

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    response
      .status(500)
      .json({
        statusCode: 500,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}

大局注册过滤器: 将过滤器类添加到大局效果域中。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AllExceptionsFilter } from './all-exceptions.filter';
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new AllExceptionsFilter());
  await app.listen(3000);
}
bootstrap();

管道

介绍

管道是类似于中间件的处理器,但具有更多的操控能力。它能够将数据转化为所需的格局,验证数据是否符合预期,并在将其传递给下一个处理程序之前,必要时转化或修改数据。

管道能够使用于以下场景:

  • 输入数据的转化和验证。
  • 操控器办法的参数绑定和验证。
  • 转化输出数据。
  • 错误处理和反常转化。

示例

创立一个管道类并完成PipeTransform接口,然后在transform()办法中编写管道逻辑。

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
  1. 使用管道: 将管道添加到操控器办法的参数装修器中。
import { Controller, Get, Post, Body, Param, UsePipes } from '@nestjs/common';
import { ParseIntPipe } from './parse-int.pipe';
@Controller('cats')
export class CatsController {
  @Post()
  @UsePipes(new ParseIntPipe())
  async create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }
}

护卫

介绍

护卫是一个能够操控器办法履行的战略的函数。它能够依据装修器的类型在不同的机遇进行履行,比方@UseGuards()装修器能够用于类和办法。

护卫能够履行以下使命:

  • 验证用户的身份或权限。
  • 拒绝未经身份验证的用户。
  • 依据路由处理程序是否被调用来履行逻辑。

示例

创立一个护卫类并完成CanActivate接口,然后在canActivate()办法中编写护卫逻辑。

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> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}

使用护卫: 在需求使用护卫的操控器类或办法上运用@UseGuards()装修器。

import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './auth.guard';
@Controller('cats')
@UseGuards(AuthGuard)
export class CatsController {
  @Get()
  findAll() {
    return [];
  }
}

总结

以上便是Nest中常用的中间件、过滤器、管道和护卫的简介和示例。在实践项目中,它们能够协助咱们更好地操控恳求流程、处理反常、验证数据等,提高代码的可维护性和可扩展性。更具体的细节更需求自己去实践操作,此处也是扼要介绍用法~