前语
近年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;
}
}
- 使用管道: 将管道添加到操控器办法的参数装修器中。
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中常用的中间件、过滤器、管道和护卫的简介和示例。在实践项目中,它们能够协助咱们更好地操控恳求流程、处理反常、验证数据等,提高代码的可维护性和可扩展性。更具体的细节更需求自己去实践操作,此处也是扼要介绍用法~