我正在将现有的nodejs+mongoose API迁移到NestJS。对于这个框架,我只是简单地按照官方网站上的文档来设置我的配置服务&模块,并重新定义我的模式以利用@nestjsmongoose
提供的装饰器。
在我的第一个API上,我只导出了一个ConfigClass,使用Nest,我有一个在控制器中调用的服务。
我想做的是根据配置的值创建一个mongoose虚拟字段。由于我的配置现在存储在一个服务中,我怀疑我是否可以直接导入它并按原样使用它。
代码方面,我当前的配置模块和服务看起来像:
//app-config.config.ts
import { registerAs } from '@nestjs/config';
export const AppConfiguration = registerAs('app', () => ({
name: process.env.APP_NAME.trim(),
host: process.env.APP_HOST.trim(),
}));
//app-config.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class AppConfigService {
constructor(private _config: ConfigService) {}
get name(): string {
return this._config.get<string>('app.name');
}
get host(): number {
return this._config.get<number>('app.host');
}
}
//app-config.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as Joi from 'joi';
import { AppConfiguration } from './app-config.config';
import { AppConfigService } from './app-config.service';
@Module({
imports: [
ConfigModule.forRoot({
load: [AppConfiguration],
validationSchema: Joi.object({
APP_NAME: Joi.string().default('nest api'),
APP_HOST: Joi.string().default('localhost.lan'),
}),
}),
],
providers: [ConfigService, AppConfigService],
exports: [AppConfigService],
})
export class AppConfigModule {}
我的模式看起来像:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
@Schema({
toObject: {
virtuals: true,
},
toJSON: {
virtuals: true,
},
})
export class Category extends Document {
@Prop({
required: true,
})
name: string;
}
export const CategorySchema = SchemaFactory.createForClass(Category);
//Before my virtual would simply look like this:
CategorySchema.virtual('access').get(function (this: Category) {
// Config would be my configuration class directly imported,
//and now accessing my config property as wished.
const url: URL = new URL('/download', Config.Host);
// What I'd like to know, now is how I should proceed to get the same result
// except with AppConfigService.host ?
url.searchParams.set('name', this.name);
return url.toString();
});
到目前为止,我考虑过在AppConfigModule构造函数中设置nodejs全局,我甚至考虑过将所需的config属性发送到客户端,并让客户端进行连接。
我正在寻找最干净的方法,我可能不知道内置的方法。
提前谢谢。如果我找到一个可以接受的解决方案,我会不断更新。
我最终在配置服务中将属性作为nodejs全局变量传递。
@Injectable()
export class AppConfigService {
get port(): number {
return this._config.get<number>('app.port');
}
get host(): string {
return this._config.get<string>('app.host');
}
get url(): string {
const _url = new URL(`${this.host}:${this.port}`);
return _url.href;
}
constructor(private _config: ConfigService) {
global.api = this.url;
}
}
我可能会将它们的声明从构造函数移到一个方法中,甚至移到我的应用程序主文件中(因为服务是在启动时调用的(。但就目前而言,它正在完成任务。