我有一个全局拦截器,需要初始化我自己的请求上下文 DTO,并且我希望可以在处理当前请求的控制器中访问此 DTO。
到目前为止我找到的解决方案是创建 Request 范围内的可注入 RequestContext 类:
import {
Injectable,
Scope
} from '@nestjs/common';
import { Request } from 'express';
import { IncomingHttpHeaders } from 'http';
@Injectable({ scope: Scope.REQUEST })
export class RequestContext {
public headers: IncomingHttpHeaders;
....
initialize(request: Request) {
this.headers = request.headers;
.....
}
}
并将此类注入拦截器:
import {
NestInterceptor,
ExecutionContext,
CallHandler,
Injectable,
Inject
} from '@nestjs/common';
import { Request } from 'express';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { RequestContext } from '../dto';
@Injectable()
export class RequestContextInterceptor implements NestInterceptor {
constructor(
@Inject(RequestContext)
protected requestContext: RequestContext
) { }
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest<Request>();
this.requestContext.initialize(request);
return next.handle()
.pipe(
tap(() => {
// decorate response
}));
}
}
然后将这个RequestContext注入到每个控制器中......
import {
Controller,
UseInterceptors,
Inject,
Get
} from '@nestjs/common';
import { BaseMicroserviceController } from '../core/base/base-microservice.controller';
import { RequestContext } from '../dto';
import { DispatchService } from '../services';
@Controller('api/v1/example')
export class ExampleController extends BaseMicroserviceController {
constructor (
@Inject(RequestContext)
protected requestContext: RequestContext,
protected dispatcheService: DispatchService
) {
super(dispatcheService);
}
@Get()
test() {
return 'test';
}
}
恕我直言,有很多解决方法可以实现这个简单的功能
另外,我有这篇文章描述了为什么使用基于范围的注入不好:https://guxi.me/posts/why-you-should-avoid-using-request-scope-injection-in-nest-js/ https://guxi.me/posts/why-you-should-avoid-using-request-scope-injection-in-nest-js/
我的服务将会非常庞大,有大量的控制器和大量的可注入服务。根据这篇文章 - 我的服务在性能和内存使用方面将无法扩展。
我的问题是如何在 NestJS 中实现我需要的功能以及最佳实践是什么?
另一个“额外问题” - RequestContext 类有initialize
接收明确请求并解析它的方法。我不喜欢它,我希望此类的每个属性都是只读的,并通过调用构造函数以传统方式初始化此类request
对象...我怎样才能实现它@Inject
战略?