I have the following IP and Ports but I want to carry this with environment variables so that they can be edited from there
import { ClientsModuleOptions, Transport } from "#nestjs/microservices"
export const GatewayOptions: ClientsModuleOptions = [
{
name: 'MICRO-ADMIN',
transport: Transport.TCP,
options: {
host: '127.20.20.2',
port: 4000,
},
},
{
name: 'MICRO-DEV',
transport: Transport.TCP,
options: {
host: '127.30.30.3',
port: 5000,
},
},
];
I import this configuration to the module.
import { Module } from '#nestjs/common';
import { ClientsModule } from '#nestjs/microservices';
import { GatewayOptions } from 'src/utils/gateway/gateway';
import { AuthModule } from './../auth/auth.module';
import { CategoryModule } from './../category/category.module';
import { GameController } from './game.controller';
import { GameService } from './game.service';
#Module({
imports: [
AuthModule,
CategoryModule,
ClientsModule.register(GatewayOptions)
],
controllers: [GameController],
providers: [GameService],
exports: [GameService],
})
export class GameModule {}
You need to use register async to use ConfigService
Follow the documentation: https://docs.nestjs.com/microservices/basics#client
#Module({
providers: [
{
provide: 'MATH_SERVICE',
useFactory: (configService: ConfigService) => {
const mathSvcOptions = configService.getMathSvcOptions();
return ClientProxyFactory.create(mathSvcOptions);
},
inject: [ConfigService],
}
]
...
})
Here is how you can configure the ConfigService: https://docs.nestjs.com/techniques/configuration#configuration
Related
I have run yarn comment to install a new package added by my teammate, after doing that it showing this error.
Argument of type '{ imports: (typeof TypeOrmConfigModule)[]; inject: (typeof ConfigService)[]; name: "default"; useExisting: typeof TypeOrmConfigService; connectionFactory: (options: any) => Promise<...>; }' is not assignable to parameter of type 'TypeOrmModuleAsyncOptions'.
Object literal may only specify known properties, and 'connectionFactory' does not exist in type 'TypeOrmModuleAsyncOptions'.
57 connectionFactory: async (options) => {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58 const connection = await createConnection(options);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 return connection;
~~~~~~~~~~~~~~~~~~~~~~~~~~
60 },
My app. modele .ts file. error is on 57 number line.
/**dependencies */
import { HttpModule } from '#nestjs/axios';
import { MiddlewareConsumer, Module, NestModule } from '#nestjs/common';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { RouterModule } from '#nestjs/core';
import { TypeOrmModule } from '#nestjs/typeorm';
import { createConnection } from 'typeorm';
/**controllers */
import { AppController } from './app.controller';
/**services */
import { AppService } from './app.service';
import { AdminModule } from './modules/admin/admin.module';
import { MasterdataModule } from './modules/admin/masterdata';
import { UniCareerModule } from './modules/admin/uni-career';
import { AgentModule } from './modules/agent/agent.module';
import { CounsellorModule } from './modules/counsellor/counsellor.module';
import { MentorModule } from './modules/mentor/mentor.module';
import { StudentModule } from './modules/student/student.module';
import { StudyModule } from './modules/study/study.module';
import { UniversityModule } from './modules/university/university.module';
import { PublicApiModule } from './public-api';
import { PublicUniversityModule } from './public-api/university';
/**validate env config */
import { validate } from './uni-engine/config/env.validation';
import {
TypeOrmConfigModule,
TypeOrmConfigService,
} from './uni-engine/config/typeorm-config';
import { MailModule } from './uni-engine/mail/mail.module';
/** logger middleware */
import { LoggerMiddleware } from './uni-engine/middleware';
/**modules */
import { UniEngineModule } from './uni-engine/uni-engine.module';
import { UniEngineService } from './uni-engine/uni-engine.service';
import { OnlineLearningModule } from './modules/online-learning/online-learning.module';
import { ScheduleModule } from '#nestjs/schedule';
import { UniChatModule } from './modules/uni-chat/uni-chat.module';
#Module({
imports: [
/**initialize nest js config module */
ConfigModule.forRoot({
validate: validate,
//responsible for use config values globally
isGlobal: true,
}),
//type orm dependencies integration
TypeOrmModule.forRootAsync({
imports: [TypeOrmConfigModule],
inject: [ConfigService],
// Use useFactory, useClass, or useExisting
// to configure the ConnectionOptions.
name: TypeOrmConfigService.connectionName,
useExisting: TypeOrmConfigService,
// connectionFactory receives the configured ConnectionOptions
// and returns a Promise<Connection>.
connectionFactory: async (options) => {
const connection = await createConnection(options);
return connection;
},
}),
//module prefix for modules
RouterModule.register([
//module prefix for admin
{
path: 'admin',
module: AdminModule,
},
{
path: 'admin',
module: MasterdataModule,
},
//module prefix for uni career module
{
path: 'uni-career',
module: UniCareerModule,
},
//module prefix for study module
{
path: 'study',
module: StudyModule,
},
//module prefix for university module
{
path: 'university',
module: UniversityModule,
},
{
path: 'public',
module: PublicApiModule,
},
{
path: 'public',
module: PublicUniversityModule,
},
{
path: 'student',
module: StudentModule,
},
{
path: 'counsellor',
module: CounsellorModule,
},
{
path: 'agent',
module: AgentModule,
},
{
path: 'mentor',
module: MentorModule,
},
{
path: 'online-learning',
module: OnlineLearningModule,
},
]),
UniEngineModule,
AdminModule,
StudyModule,
MailModule,
PublicApiModule,
UniversityModule,
HttpModule,
StudentModule,
CounsellorModule,
MentorModule,
AgentModule,
OnlineLearningModule,
//scheduler module
ScheduleModule.forRoot(),
UniChatModule,
],
controllers: [AppController],
providers: [AppService, UniEngineService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
}
It was running code. I have just run a yarn command. This project is running on other computers with the same Node Version and yarn version. How can I solve the issue?
I want to know if it possible to inject ConfigService into module import:
import { Module } from '#nestjs/common';
import { FileService } from './file.service';
import { FileResolver } from './file.resolver';
import { FileUploadController } from './contollers/file-upload.controller';
import { S3Service } from './host/s3.service';
import { AwsSdkModule } from 'nest-aws-sdk';
import { S3, SharedIniFileCredentials } from 'aws-sdk';
#Module({
controllers: [FileUploadController],
providers: [FileService, FileResolver, S3Service],
exports: [FileService, FileResolver],
imports: [
ConfigService.forRoot(),
AwsSdkModule.forRoot({
// use config service here
// configService.get('some-value')
defaultServiceOptions: {
region: 'us-east-1',
credentials: new SharedIniFileCredentials({
profile: 'my-profile',
}),
},
services: [S3],
}),
],
})
export class StorageModule {}
is it possible to use the configService inside AwsSdkModule provider?
Maybe you could try
AwsSdkModule.forRootAsync({
imports: [ConfigService],
inject: [ConfigService],
useFactory: (configService: ConfigService) {
}
})
You can try this.
AwsSdkModule.forRootAsync({
defaultServiceOptions: {
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
region: configService.get('region'),
credentials: {
accessKeyId: configService.get('access_key'),
secretAccessKey: configService.get('secret_key'),
},
}),
},
services: [S3],
})
I'm trying to setup configuration for my NestJS app by following some of the following documentation:
Config: https://docs.nestjs.com/techniques/configuration
TypeORM: https://docs.nestjs.com/techniques/database#async-configuration
I've added a .env file to the root of my project (same level as package.json) with the following values:
DB_URL=localhost
DB_USER=root
DB_PASSWORD=root
DB_NAME=test_db
In my app.module.ts, I import the following modules:
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
#Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => {
// The value logged below is undefined'
console.log(`DB URL: ${configService.get('DB_URL')}`);
return {
type: 'mysql',
host: configService.get('DB_URL'),
port: 3306,
username: configService.get('DB_USER'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: false,
migrations: ['dist/migrations/*{.js}'],
cli: {
migrationsDir: 'migrations',
},
};
},
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
As noted above, the value retrieved by configService.get('DB_URL') is undefined. Was hoping for any help/advice on how to set up the configuration so that I could read the values in my .env file when starting up the application.
The admin-bro-nestjs repository contains a comprehensive example with example with mongoose. But I need use it with typeorm and postgres.
I tried to adapt this example for typeorm:
// main.ts
import AdminBro from 'admin-bro';
import { Database, Resource } from '#admin-bro/typeorm';
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
AdminBro.registerAdapter({ Database, Resource });
const bootstrap = async () => {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
and
// app.module.ts
import { Module } from '#nestjs/common';
import { AdminModule } from '#admin-bro/nestjs';
import { TypeOrmModule, getRepositoryToken } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserEntity } from './user/user.entity';
#Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: 'database_test',
entities: [UserEntity],
synchronize: true,
logging: false,
}),
AdminModule.createAdminAsync({
imports: [
TypeOrmModule.forFeature([UserEntity]),
],
inject: [
getRepositoryToken(UserEntity),
],
useFactory: (userRepository: Repository<UserEntity>) => ({
adminBroOptions: {
rootPath: '/admin',
resources: [
{ resource: userRepository },
],
},
auth: {
authenticate: async (email, password) => Promise.resolve({ email: 'test' }),
cookieName: 'test',
cookiePassword: 'testPass',
},
}),
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
But on application start I get the following error:
NoResourceAdapterError: There are no adapters supporting one of the resource you provided
Does anyone have any experience putting all these libraries together?
I also got NoResourceAdapterError: There are no adapters supporting one of the resource you provided when I tried to integrate AdminBro with NestJS/Express/TypeORM (though I'm using MySQL instead Postgres). The solution posted in the admin-bro-nestjs Github issue which links to this question didn't help me.
The cause of NoResourceAdapterError for me simply was that UserEntity didn't extend BaseEntity. NestJS/TypeORM seems to work fine without extending BaseEntity but apparently it is required for AdminBro. You can see it used in the examples of the AdminBro TypeORM adapter documentation.
Here is an example which works for me.
// user.entity
import { Entity, BaseEntity, Column, PrimaryGeneratedColumn } from 'typeorm';
#Entity()
export class UserEntity extends BaseEntity{
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
}
// app.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AdminModule } from '#admin-bro/nestjs';
import { Database, Resource } from '#admin-bro/typeorm';
import AdminBro from 'admin-bro'
AdminBro.registerAdapter({ Database, Resource });
#Module({
imports: [
TypeOrmModule.forRoot({
// ...
}),
AdminModule.createAdmin({
adminBroOptions: {
resources: [UserEntity],
rootPath: '/admin',
},
})
],
// ...
})
Is there a way to connect multiple MongoDB connections per module?
app.module.ts
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/masterDB'),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
Similarly, can we define another connection in another module which is a child of app.module?
child.module.ts
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/childDB'),
MongooseModule.forFeature([{ name: 'child', schema: ChildSchema }]),
],
controllers: [ChildController],
providers: [ChildService],
})
export class ChildModule { }
Or any other way to access different databases at once.
Thanks in advance!
[SOLVED March 2021]
Here you'll find the solution:
https://www.learmoreseekmore.com/2020/04/nestjs-multiple-mongodb-databases.html
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { studentSchema } from './schemas/myworld/student.schema';
import { animalSchema } from './schemas/wildlife/animal.schema';
#Module({
imports: [
MongooseModule.forFeature([
{
name: 'Student',
schema: studentSchema,
collection: 'Student',
},
],'myWorldDb'),
MongooseModule.forFeature([
{
name: 'Animals',
schema: animalSchema,
collection: 'Animals'
}
],'wildLifeDb'),
MongooseModule.forRoot(
'mongodb+srv://<userName>:<password>#cluster0-igk.mongodb.net/MyWorld?retryWrites=true&w=majority',
{
connectionName: 'myWorldDb'
}
),
MongooseModule.forRoot(
'mongodb+srv://<username>:<password>#cluster0-igk.mongodb.net/WildLife?retryWrites=true&w=majority',
{
connectionName: 'wildLifeDb'
}
)
],
controllers: [],
providers: [],
})
export class AppModule {}
You have to do it manually you have to use a providers file:
mongoose.providers.ts
import * as mongoose from 'mongoose';
export const mongooseProviders = [
{
provide: 'MASTER_CONNECTION',
useFactory: (): Promise<typeof mongoose> =>
// This mongoose.connect never working for multples DB connection
// mongoose.connect('mongodb://localhost/masterDB'),
// Following is working fine and tested by me
mongoose.createConnection('mongodb://localhost/masterDB'),
},
{
provide: 'CHILD_CONNECTION',
useFactory: (): Promise<typeof mongoose> =>
// This mongoose.connect never working for multples DB connection
// mongoose.connect('mongodb://localhost/masterDB'),
// Following is working fine and tested by me
mongoose.createConnection('mongodb://localhost/ChildDB'),
},
];
mongoose.module.ts
import { Module } from '#nestjs/common';
import { mongooseProviders } from './mongoose.providers';
#Module({
providers: [...mongooseProviders],
exports: [...mongooseProviders],
})
export class MongooseModule {}
model.providers.ts
import { Connection } from 'mongoose';
import { ChildSchema } from './schemas/child/child.schema';
import { MasterSchema } from './schemas/master/master.schema';
export const modelProviders = [
{
provide: 'CHILD_MODEL',
useFactory: (connection: Connection) => connection.model('Child', ChildSchema),
inject: ['CHILD_CONNECTION'],
},
{
provide: 'MASTER_MODEL',
useFactory: (connection: Connection) => connection.model('Master', MasterSchema),
inject: ['MASTER_CONNECTION'],
},
];
And on the constructor instead of using #InjectModel you use #Inject:
#Injectable
export Class ModelService {
constructor(#Inject('MASTER_MODEL') private masterModel: Model<Master>) {}
...
Note: in the module you provide the service you should import the MongooseModule and put as provider modelProviders.
Post above from RalphJS really helped, but it only was using one connection for everything. Had to change 1 thing in model.providers.ts:
instead of mongoose.connect
you have to use mongoose.createConnection
model.providers.ts
import * as mongoose from 'mongoose';
export const mongooseProviders = [
{
provide: 'MASTER_CONNECTION',
useFactory: async (): Promise<unknown> =>
await mongoose.createConnection('mongodb://localhost/masterDB'),
},
{
provide: 'CHILD_CONNECTION',
useFactory: async (): Promise<unknown> =>
await mongoose.createConnection('mongodb://localhost/childDB'),
},
];
https://mongoosejs.com/docs/connections.html#multiple_connections