在Nestjs中应用中间件。还是在Nestjs中正确使用swagger-ui-express软件包?

时间:2019-06-06 15:25:20

标签: swagger nestjs

我有监听路径/ API的API。 (代码临时在此处https://github.com/vit100/nest-middleware-test

为根应用了中间件(提供静态swagger文件),如下所示:

// app.module.ts------------
import { F1, F2, F3 } from './swaggerMiddleware';

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): void | MiddlewareConsumer {
  consumer.apply(F1, F2, F3).exclude('/api').forRoutes('/');
  }
}
// end of app.module.ts------------

//swaggerMiddleware.ts-------------------------

import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response } from 'express';
import yamljs from 'yamljs';
import swaggerUiExpress from 'swagger-ui-express';

const yamlDoc = yamljs.load(__dirname + '\\swagger.yaml');

@Injectable()
export class F1 implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    if (req.url.includes('api')) {
      return next();
    }
    req.url = req.originalUrl;
    return swaggerUiExpress.serve[0].call(this, req, res, next);
  }
}


@Injectable()
export class F2 implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    if (req.url.includes('api')) {
      return next();
    }
    req.url = req.originalUrl;
    return swaggerUiExpress.serve[1].call(this, req, res, next);
  }
}


@Injectable()
export class F3 implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    if (req.url.includes('api')) {
      return next();
    }
    req.url = req.originalUrl;
    return swaggerUiExpress.setup(yamlDoc).call(this, req, res, next);
  }
}
//end of swaggerMiddleware.ts-------------------------

我没有找到另一种集成swaggerUiExpress的方法。不幸的是,我不得不将调用分为单独的中间件类。 类而不是函数-因为.exclude('/api')不适用于函数中间件。还必须重新分配req.url = req.originalUrl;,因为它在某处丢失了...

它开始起作用,但是我不知道。对我来说,这很腥 还是应该采用另一种方式来服务于这种逻辑,例如这种笨拙的中间件?

1 个答案:

答案 0 :(得分:0)

无论您的用例如何,我都不认为这是一种好方法。您将在每个请求上加载一个yaml文件,该文件超出范围,会收集垃圾并从文件系统中重新读取下一个请求。您应该将文件加载到请求之外,然后从内存中提供文件。 编辑:如果您需要根据更改刷新文件,则可以使用req

关于为什么它不起作用,您正在同一resnextnext对象上调用两个不同的中间件。但是,当您在第一个中间件上调用next时,它将切换到框架链接并在next中引用的下一个中间件。到您的第二个中间件调用import swaggerUiExpress from 'swagger-ui-express'; import yamljs from 'yamljs'; const yamlDoc = yamljs.load(__dirname + '\\swagger.yaml'); export function swaggerMiddleware(req, res, next) { swaggerUiExpress.serve[0](req, res, function (req, res) { swaggerUiExpress.setup(yamlDoc)(req, res, next) }); ); } 时,框架已经开始编写响应请求周期结束的响应。您需要做的是自己传递这些中间件,方法是将第二个中间件作为第一个中间件的下一个处理程序传递。像这样

([^\s]+\s+[^\s]+|[^\s]+)