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(支持依赖注入)。

相关推荐
Java编程爱好者13 分钟前
手把手看懂 Java 字节码:讲透 Integer 判等、静态方法重写与 try-finally 核心底层
后端
踏浪无痕20 分钟前
k8s发布服务,nacos未服务未下线紧急处理流程
后端
TYKJ02321 分钟前
物理安全:顶级机房为什么需要刷脸+指纹+工牌
后端
程序员黑豆27 分钟前
AI全栈开发 - Java:注释
前端·后端·ai编程
小二·44 分钟前
Spring Boot 3 + Vue 3 全栈开发实战
vue.js·spring boot·后端
仿生joe会梦见漫天的大雪吗1 小时前
CTF学习笔记03:密码口令 —— 从弱口令到字典爆破
后端
自进化Agent智能体1 小时前
从零到一玩转Hermes Agent:VPS部署 × 模型配置 × 记忆架构 × 多Agent协作
后端
用户4682557459131 小时前
Testcontainers 在 Windows Docker Desktop 上跑不通:协议层不兼容 + 4 种可行环境
java·后端
Tenaryo1 小时前
「底层系统基石 · 缓存篇」V —— 写策略、Store Buffer 与内存屏障
后端·面试