Nest 中间件 Middleware - 就像 Vue 的路由守卫

1. 先说 Vue 里的"中间件"

你有没有在 Vue 里用过这些?

场景一:路由守卫

javascript 复制代码
// Vue 路由守卫
router.beforeEach((to, from, next) => {
  console.log('跳转前');
  next();  // 放行
});

每次页面跳转,都会先经过这个"拦截器"。

场景二:axios 请求拦截器

javascript 复制代码
// 请求发送前
axios.interceptors.request.use(config => {
  config.headers.Authorization = 'Bearer token';
  return config;
});

这就是中间件 的思想:在请求进入之前、响应返回之后,偷偷干点别的事。


2. Nest 的 Middleware 是什么?

Nest 也有中间件,但和 Express 的不完全一样。

最大区别 :Nest 的 Middleware 支持依赖注入!

typescript 复制代码
@Injectable()
export class AaaMiddleware implements NestMiddleware {
  // 可以注入 Service!
  @Inject(AppService)
  private readonly appService: AppService;

  use(req: Request, res: Response, next: () => void) {
    console.log('请求前');
    next();  // 放行
    console.log('响应后');
  }
}

3. 怎么用?三步走

第 1 步:创建 Middleware

bash 复制代码
nest g middleware aaa --no-spec --flat

第 2 步:写业务逻辑

typescript 复制代码
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express';

@Injectable()
export class AaaMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    console.log('请求前');
    next();  // 放行到下一个中间件或 Controller
    console.log('响应后');
  }
}

第 3 步:在 Module 中注册

typescript 复制代码
@Module({
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(AaaMiddleware).forRoutes('*');  // 作用于所有路由
  }
}

4. 可以精确控制作用于哪些路由

typescript 复制代码
configure(consumer: MiddlewareConsumer) {
  // 只作用于 /hello 开头的 GET 请求
  consumer.apply(AaaMiddleware).forRoutes({
    path: 'hello*',
    method: RequestMethod.GET
  });
}

对比 Vue:

javascript 复制代码
// Vue 中精确控制
router.beforeEach((to, from, next) => {
  if (to.path.startsWith('/hello')) {
    console.log('只拦截 /hello 开头');
  }
  next();
});

5. 为什么要用 Class 形式的 Middleware?

当然是为了依赖注入!

typescript 复制代码
@Injectable()
export class AaaMiddleware implements NestMiddleware {
  // 可以注入别的 Service!
  constructor(private readonly appService: AppService) {}

  use(req: Request, res: Response, next: () => void) {
    // 调用 Service 的方法
    console.log(this.appService.getHello());
    next();
  }
}

Vue 对比:Vue 的路由守卫里也可以调用 Vuex/Pinia 的 actions!


6. 不注入依赖?也可以用函数形式

typescript 复制代码
// 如果不需要注入依赖,可以简写成函数
const loggerMiddleware = (req, res, next) => {
  console.log('请求前');
  next();
};

configure(consumer: MiddlewareConsumer) {
  consumer.apply(loggerMiddleware).forRoutes('*');
}

这就和 Express 的 middleware 一样了。


7. Middleware vs Interceptor - 区别是啥?

特性 Middleware Interceptor
能否拿到目标 Handler ❌ 不能 ✅ 可以
能否用 RxJS ❌ 不能 ✅ 可以
适用场景 通用逻辑(日志、CORS) 业务相关(统一返回格式)
typescript 复制代码
// Interceptor 可以拿到目标 Handler
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
  const handler = context.getHandler();  // 拿到目标方法
  console.log('目标:', handler);
  return next.handle();
}

Vue 对比:

  • Middleware = 路由守卫(通用)
  • Interceptor = axios 拦截器(业务相关)

8. 完整流程图

复制代码
请求进来
   │
   ▼
┌──────────────────────────────────────┐
│  Middleware(请求前后)               │  ← 可以在这里打印日志、权限校验
└──────────────────────────────────────┘
   │
   ▼
┌──────────────────────────────────────┐
│  Guard(权限判断)                   │
└──────────────────────────────────────┘
   │
   ▼
┌──────────────────────────────────────┐
│  Interceptor(响应前后)              │  ← 可以统一处理返回值、计时
└──────────────────────────────────────┘
   │
   ▼
  Controller(业务逻辑)

9. 总结

概念 Vue 类比 作用
Middleware router.beforeEach 请求前后执行逻辑
NestModule - 注册 Middleware
MiddlewareConsumer - 精确控制作用于哪些路由

一句话总结:

Nest 的 Middleware 就是支持依赖注入的路由守卫,可以在请求前后执行通用逻辑。

和 Express 的区别:Express 的 middleware 是函数,Nest 的 middleware 是 class(支持依赖注入)。

相关推荐
特立独行的猫A3 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
码事漫谈6 小时前
我花了一周时间,看AI公司怎么"管"AI,结果越看越后背发凉
后端
濮水大叔8 小时前
Cabloy/Vona 为什么不需要 NestJS 的 Dynamic Module
typescript·node.js·nestjs
爱学习的程序媛8 小时前
Python常用框架梳理
开发语言·后端·python·ai·web·后端框架·python框架
GISer_Jing9 小时前
Agent核心内容
后端·ai·langchain
budingxiaomoli10 小时前
Spring统一功能处理
java·后端·spring
某鹏11 小时前
网关选型:Go、Java、Graal 谁都不能完胜
后端
用户02478365309711 小时前
从屎山到防线:14 行状态迁移表,给任务系统装上防瞎跳闸门
后端
CQU_JIAKE11 小时前
11.13[体系结构】指标,五级流水线,八级流水线,虚实地址思考
后端
panbook13 小时前
从0到1实现一个分布式时序数据库(三):主从复制、故障检测与切换
后端