You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS中实现模块向中间件传递数据?

解决方案

核心问题拆解

  1. 全局前缀api会自动给所有路由添加前缀,但需要在传入context时使用自定义路径(跳过全局前缀),无context时沿用api/matrix/version
  2. 当前代码用静态类属性传递路径不符合依赖注入规范,且中间件匹配所有GET请求效率低下
  3. 废弃的with()方法无需纠结,改用NestJS现有API实现需求

修改后的代码实现

1. matrix.module.ts

import { DynamicModule, MiddlewareConsumer, Module, RequestMethod, Provider } from "@nestjs/common";
import { MatrixService } from "./services/matrix.service";
import { MatrixMiddleware } from "./middleware/matrix-middleware";

// 定义路径注入的Token,用于传递动态路径
export const MATRIX_PATH = 'MATRIX_PATH';

@Module({
    providers: [MatrixService],
    exports: [MatrixService],
})
export class MatrixModule {
    static forRoot(context?: string): DynamicModule {
        // 计算目标路径:传context则用自定义绝对路径,否则用基础路径(全局前缀会自动拼接)
        const targetPath = context 
            ? `/${context}/matrix/version`
            : '/matrix/version';

        // 将路径注册为可注入的依赖,取代静态类属性
        const pathProvider: Provider = {
            provide: MATRIX_PATH,
            useValue: targetPath,
        };

        return {
            module: MatrixModule,
            providers: [MatrixService, pathProvider],
            exports: [MatrixService, pathProvider],
            global: true,
        };
    }

    configure(consumer: MiddlewareConsumer) {
        consumer.apply(MatrixMiddleware)
            .forRoutes({ path: "*", method: RequestMethod.GET });
    }
}

2. matrix-middleware.ts

import { Injectable, NestMiddleware, Inject } from '@nestjs/common';
import { Response, Request, NextFunction } from 'express';
import { MatrixService } from '../services/matrix.service';
import { MATRIX_PATH } from '../matrix.module';

@Injectable()
export class MatrixMiddleware implements NestMiddleware {
    constructor(
        private readonly matrixService: MatrixService,
        @Inject(MATRIX_PATH) private readonly targetPath: string,
    ) {}

    use(req: Request, res: Response, next: NextFunction) {
        // 拆分原始URL,忽略查询参数
        const requestPath = req.originalUrl.split('?')[0];
        let isTargetRequest = false;

        // 分情况判断请求路径:
        // 1. 有context时,直接匹配自定义绝对路径(跳过全局前缀)
        if (this.targetPath.startsWith('/') && !this.targetPath.startsWith('/api/')) {
            isTargetRequest = requestPath === this.targetPath;
        } 
        // 2. 无context时,匹配全局前缀拼接后的完整路径
        else {
            isTargetRequest = requestPath === `/api${this.targetPath}`;
        }

        if (isTargetRequest) {
            const appVersion = this.matrixService.getVersion();
            res.status(200).json({ version: appVersion });
        } else {
            next();
        }
    }
}

关键优化点

  • 依赖注入传递路径:用MATRIX_PATH Token将动态路径注入中间件,避免静态类属性的全局污染问题,符合NestJS设计规范
  • 精准路径判断:通过req.originalUrl获取完整请求路径,兼容有无全局前缀的场景,无需提前配置路由排除规则
  • 性能提升:虽然中间件仍匹配所有GET请求,但内部通过精准判断快速过滤非目标请求,实际性能影响可忽略

内容的提问来源于stack exchange,提问作者Cheburechek7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:22:47