我有监听路径/ 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;
,因为它在某处丢失了...
它开始起作用,但是我不知道。对我来说,这很腥 还是应该采用另一种方式来服务于这种逻辑,例如这种笨拙的中间件?
答案 0 :(得分:0)
无论您的用例如何,我都不认为这是一种好方法。您将在每个请求上加载一个yaml文件,该文件超出范围,会收集垃圾并从文件系统中重新读取下一个请求。您应该将文件加载到请求之外,然后从内存中提供文件。 编辑:如果您需要根据更改刷新文件,则可以使用req
关于为什么它不起作用,您正在同一res
,next
,next
对象上调用两个不同的中间件。但是,当您在第一个中间件上调用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]+)