NestJS核心概念之Middleware中间件创建使用示例
作者:南玖
这篇文章主要为大家介绍了NestJS核心概念之Middleware中间件创建使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
前言
用过express
与koa
的同学,对中间件这个概念应该非常熟悉了,中间件可以拿到Request
、Response
对象和next
函数.
一般来讲中间件有以下作用:
- 执行任何代码
- 对请求与响应拦截并改造
- 结束
request-response
周期 - 通过
next()
调用下一个中间件 - 如果当前中间件没有结束当前
request-response
周期,必须调用next()
函数,否则请求会处于挂起状态,阻塞整个应用
中间件一般有两种:类中间件、函数中间件
类中间件
创建类中间件
使用@Injectable()
装饰器,并且需要实现NestMiddleware
接口(use
方法)
// Logger.middleware.ts import { Injectable, NestMiddleware } from "@nestjs/common"; import { Request, Response } from "express"; @Injectable() export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: () => void) { console.log('logger middleware', `url: ${req.url}`); next(); } }
使用类中间件
类中间创建完之后,需要在模块中进行挂载,但@Module
装饰器并没有中间件的相关配置,我们需要让module
类实现NestModule
接口,实现里面configure方法来进行挂载
// user.module.ts import { Module, NestModule } from '@nestjs/common'; import { UserService } from './user.service'; import { UserController } from './user.controller'; import { LoggerMiddleware } from '../middleware/Logger.middleware'; @Module({ controllers: [UserController], providers: [UserService] }) export class UserModule implements NestModule { configure(consumer) { consumer .apply(LoggerMiddleware) .forRoutes(UserController); } }
apply
方法表示挂载的是哪个中间件forRoutes
方法表示对哪个请求路径起作用,这种方式与app.use(path, middleware)
作用是一样,只针对部分路径起作用- 当给
forRoutes
方法传递的是一个controller
控制器时,那么该中间件则对整个控制器下的路径生效
比如这里传递的是UserController
控制器,那么针对该控制器下的路径都会生效
forRootes
方法还能做更详细的配置,比如可以针对特定的请求方法、请求路径可以使用正则匹配(需要注意的是使用fastify
驱动不能使用)
export class UserModule implements NestModule { configure(consumer) { consumer .apply(LoggerMiddleware) .forRoutes({ path: 'user', method: RequestMethod.GET}); } }
apply
可以同时挂载多个中间件
export class UserModule implements NestModule { configure(consumer) { consumer .apply(LoggerMiddleware, aaaMiddleware, ...) .forRoutes({ path: 'user', method: RequestMethod.GET}); } }
forRoutes
可以使用单个string
路径,多个string
路径,RouteInfo
对象,单个Controller
,多个Controller
export class AppModule implements NestModule { configure(consumer) { consumer .apply(LoggerMiddleware, NjMiddleware, ...) .forRoutes(UserController, NjController, ...); } }
exclude
可以用来排除不使用中间件的路径
export class UserModule implements NestModule { configure(consumer) { consumer .apply(LoggerMiddleware) .exclude({ path: '/user/a', method: RequestMethod.GET}) .forRoutes(UserController); } }
需要注意的是forRoutes
需要最后调用
函数中间件
这种方式较为简单,使用起来与类中间件一致
创建函数中间件
export function LoggerMiddleware(req: Request, res: Response, next: () => void) { console.log('logger middleware', `url: ${req.url}`); next(); }
使用函数中间件
export class UserModule implements NestModule { configure(consumer) { consumer .apply(LoggerMiddleware) .exclude({ path: '/user/a', method: RequestMethod.GET}) .forRoutes(UserController); } }
全局中间件
可以直接在入口文件main.ts
中使用app.use
来挂载中间件,这样挂载的中间件将全局生效
app.use(LoggerMiddleware) // 日志中间件
中间件其实可以用来实现很多功能,比如:日志系统、cors跨域处理、图片防盗等...
对图片防盗感兴趣的可以看我这篇文章:你不知道的 HTTP Referer
以上就是NestJS核心概念之Middleware中间件创建使用示例的详细内容,更多关于NestJS Middleware中间件的资料请关注脚本之家其它相关文章!