Maybe I am missing a basic thing as I am starting out with Nestjs, but somehow I can't get Nest.js to receive messages in a Pub/Sub pattern using: https://github.com/golevelup/nestjs. I create the Messaging Service like so:
#Module({
imports: [
RabbitMQModule.forRoot(RabbitMQModule, {
exchanges: [
{
name: 'tx-nextor',
type: 'topic',
},
],
uri: RABBIT_URI,
channels: {
'channel-1': {
prefetchCount: 15,
default: true,
},
},
}),
MessagingModule,
],
providers: [],
controllers: [],
})
export class MessagingModule {}
Everything is connecting correctly and I can see the connection and channel in the RabbitMQ admin. After I created a subscriber:
#Injectable()
export class ResourceService {
#RabbitSubscribe({
exchange: 'tx-nextor',
routingKey: 'resource.*',
queue: 'resource-history-resource.*.updated',
})
public async updatedHandler(msg: {}, amqpMsg: ConsumeMessage) {
console.log('Subscribe handler ran');
console.log(JSON.stringify(msg));
console.log(`Correlation id: ${amqpMsg.properties.correlationId}`);
return 'test';
}
}
This also connects:
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RoutesResolver] AppController {/}: +8ms
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RouterExplorer] Mapped {/, GET} route +3ms
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RoutesResolver] HistoryController {/history}: +1ms
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RouterExplorer] Mapped {/history/appointment, GET} route +1ms
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RouterExplorer] Mapped {/history/test, POST} route +1ms
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RabbitMQModule] Initializing RabbitMQ Handlers
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RabbitMQModule] Registering rabbitmq handlers from ResourceService
[resource-history] [Nest] 220 - 07/09/2022, 4:30:47 PM LOG [RabbitMQModule] ResourceService.updatedHandler {subscribe} -> tx-nextor::resource.*::resource-history-resource.*.updated
[resource-history] [Nest] 220 - 07/09/2022, 4:30:48 PM LOG [NestApplication] Nest application successfully started +11ms
But after I do this nothing is logged.
Although the consumer is connected, all testmessages are staying on the queue:
Adding RabbitMQModule to the exports in the Module definition solved the issue for me.
Reference: Problems with RabbitMQ and NestJS. I can't publish a message with nestjs-rabbitmq and NestJS
#Module({
imports: [
RabbitMQModule.forRoot(RabbitMQModule, {
exchanges: [
{
name: 'tx-nextor',
type: 'topic',
},
],
uri: RABBIT_URI,
channels: {
'channel-1': {
prefetchCount: 15,
default: true,
},
},
}),
MessagingModule,
],
providers: [],
controllers: [],
exports: [RabbitMQModule],
})
export class MessagingModule {}
Also, in the RabbitMQ Admin, make sure the payload has "" in the value, so it would be "test" vs test (sending JSON also should work)
Hope this helps!
Related
To add http://localhost:8080/api/v1/admin (GET) to develop an api with NestJS, we added Get annotation and proceeded with the api development, but the api was not mapped, and if you call that api, a 404notfound error will occur.
What kind of problem?
// admin.controller.ts
import { Body, Controller, Get, HttpCode, Post, UseGuards } from '#nestjs/common';
import {
ApiTags,
ApiOperation,
ApiResponse,
} from '#nestjs/swagger';
import { ReqAdmin } from 'src/lib/decorator/req-admin.decorator';
import { HttpAuthGuard } from 'src/guards/auth/http-auth.guard';
import { BaseResponse } from 'src/models/http/base.response';
import { AdminService } from './admin.service';
import { CreateAdminDto } from './dto/create.admin.dto';
import { LoginAdminDto } from './dto/login.admin.dto';
import { Admin } from 'src/entities/admin.entity';
#Controller('admin')
#ApiTags('관리자 API')
export class AdminController {
constructor(
private readonly adminService: AdminService
) {}
#Get('/')
#UseGuards(HttpAuthGuard)
#ApiOperation({ summary: '내 정보 보기', description: '내정보 보기' })
#ApiResponse({ status: 200, description: '내 정보 조회 성공' })
public async findOne(#ReqAdmin() admin: Admin): Promise<BaseResponse> {
const data = await this.adminService.findOneById(admin.id);
return BaseResponse.object('내정보 조회 성공', {
data,
})
}
#Post('/')
#ApiOperation({ summary: '관리자 생성 API', description: '관리자를 생성한다.' })
#ApiResponse({ status: 201, description: '관리자 생성성공' })
public async create(#Body() createAdminDto: CreateAdminDto) {
await this.adminService.create(createAdminDto);
return BaseResponse.object('관리자 생성성공')
}
#Post('/login')
#HttpCode(200)
#ApiOperation({ summary: '관리자 로그인 API', description: '관리자 로그인' })
#ApiResponse({ status: 200, description: '관리자 로그인성공', type: String })
public async login(#Body() loginAdminDto: LoginAdminDto) {
const token = await this.adminService.login(loginAdminDto);
return BaseResponse.object('관리자 로그인성공', {
'x-access-token': token
})
}
}
// admin.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { Admin } from 'src/entities/admin.entity';
import { TokenModule } from 'src/token/token.module';
import { TokenService } from 'src/token/token.service';
import { AdminController } from './admin.controller';
import { AdminRepository } from './admin.repository';
import { AdminService } from './admin.service';
#Module({
imports: [
TypeOrmModule.forFeature([
Admin
])
],
providers: [AdminService, TokenService],
exports: [AdminService],
controllers: [AdminController]
})
export class AdminModule {}
// terminal
iwonje#iwonje-ui-MacBookAir mcn-admin-backend % nest start
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [NestFactory] Starting Nest
application...
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [InstanceLoader] AppModule
dependencies initialized +42ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [InstanceLoader] TypeOrmModule
dependencies initialized +0ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [InstanceLoader] TypeOrmCoreModule
dependencies initialized +303ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [InstanceLoader] TypeOrmModule
dependencies initialized +0ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [InstanceLoader] AdminModule
dependencies initialized +1ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [RoutesResolver] AdminController
{/api/v1/admin}: +287ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [RouterExplorer] Mapped
{/api/v1/admin, POST} route +1ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [RouterExplorer] Mapped
{/api/v1/admin/login, POST} route +1ms
[Nest] 40115 - 2022. 10. 11. 오후 4:12:15 LOG [NestApplication] Nest application
successfully started +1ms
// app.module.ts
import { Module } from '#nestjs/common';
import { TypeOrmModule, TypeOrmModuleOptions } from '#nestjs/typeorm';
import { DatabaseTypes } from '../database/database.enum';
import { DatabaseFactory } from '../database/database.factory';
import { AdminModule } from 'src/admin/admin.module';
#Module({
imports: [
TypeOrmModule.forRoot(
DatabaseFactory.createDatabase(DatabaseTypes.MYSQL).options(),
),
AdminModule
],
})
export class AppModule {}
Look like you had added a prefix for your api /api/v1
You can try to call http://localhost:8080/api/v1/admin instead of http://localhost:8080/admin
I'm working on a telegram bot (using nestjs-telegraf). I noticed that my app fails to start loading telegraf module if network connection is absent.
[Nest] 544032 - 08/06/2022, 10:01:43 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 544032 - 08/06/2022, 10:01:43 ERROR [ExceptionHandler] request to https://api.telegram.org/bot5386725551:[REDACTED]/getMe failed, reason: getaddrinfo EAI_AGAIN api.telegram.org
FetchError: request to https://api.telegram.org/bot5386725551:[REDACTED]/getMe failed, reason: getaddrinfo EAI_AGAIN api.telegram.org
When this error occur I have to manually kill the process (CTRL-C) check the net and restart the nest's app.
How can I check if net is available before import nestjs's module or manage/intercept the EAI_AGAIN error?
this is the module that should run nestjs-telegraf that fails on net absence
import { EventModule } from './../event/event.module';
import { UsersModule } from 'src/users/users.module';
import { TowerModule } from './../tower/tower.module';
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { TelegrafModule } from 'nestjs-telegraf';
import { BotService } from './bot.service';
#Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TelegrafModule.forRoot({ token: process.env.BOT_TOKEN }),
TowerModule,
UsersModule,
EventModule,
],
providers: [BotService],
exports: [BotService],
})
export class BotModule {}
Thanks
When i trying to call some method from service im getting "Error: 14 UNAVAILABLE: No connection established"
Code in some module:
imports: [
ClientsModule.register([
{
name: 'UsersService',
transport: Transport.GRPC,
options: {
url: 'localhost:50051',
package: 'users',
protoPath: 'path/to/proto',
}
}
])
],
Users microservice:
async function bootstrap() {
const app = await NestFactory.createMicroservice(
UsersModule,
{
transport: Transport.GRPC,
options: {
url: 'localhost:50051',
package: 'users',
protoPath: 'path/to/proto',
}
},
)
}
Full error
[Nest] 3644 - 12.06.2022, 22:11:54 ERROR [ExceptionsHandler] 14 UNAVAILABLE: No connection established
Error: 14 UNAVAILABLE: No connection established
at Object.callErrorFromStatus (C:\Users\123\Desktop\projects\syntx\api-gateway\node_modules\#grpc\grpc-js\src\call.ts:81:24)
at Object.onReceiveStatus (C:\Users\123\Desktop\projects\syntx\api-gateway\node_modules\#grpc\grpc-js\src\client.ts:351:36)
at Object.onReceiveStatus (C:\Users\123\Desktop\projects\syntx\api-gateway\node_modules\#grpc\grpc-js\src\client-interceptors.ts:462:34)
at Object.onReceiveStatus (C:\Users\123\Desktop\projects\syntx\api-gateway\node_modules\#grpc\grpc-js\src\client-interceptors.ts:424:48)
at C:\Users\123\Desktop\projects\syntx\api-gateway\node_modules\#grpc\grpc-js\src\call-stream.ts:330:24
at processTicksAndRejections (node:internal/process/task_queues:78:11)
I am working on a NestJS Project that is based on micro-service architecture (Kafka, CQRS Patter).
I have created a shared mongodb database inside docker container and exposed the port to 8081 Port which is accessible via browser(I am using mongo-express ui). Here is the docker-compose.yml file
version: '3.1'
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: PWD
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
volumes:
- data-volume:/data/db
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: PWD
volumes:
data-volume:
And in my NESTJS Service, I have defined mongo connection like this: (app.module.ts)
import { Module } from '#nestjs/common';
import { APP_FILTER } from '#nestjs/core';
import { CqrsModule } from '#nestjs/cqrs';
import { MongooseModule } from '#nestjs/mongoose';
import { UserModule } from './user/user.module';
#Module({
imports: [UserModule, MongooseModule.forRoot('mongodb://localhost:8081/urooj', {
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true
})],
controllers: []
})
export class AppModule {}
And in my user module I am defining User schema: (user.module.ts)
import { Module } from '#nestjs/common';
import { CqrsModule } from '#nestjs/cqrs';
import { UserController } from './user.controller';
import { UserHandler } from "./command/handler/index";
import { MongooseModule } from '#nestjs/mongoose';
import { UserSchema } from './models/user.model';
import { UsersRepository } from './user.repository';
import { UserService } from './user.service';
#Module({
imports: [
CqrsModule,
MongooseModule.forFeature([{name: 'User', schema: UserSchema}])
],
controllers: [UserController],
providers: [
...UserHandler,
UserService
]
})
export class UserModule {}
But I am getting this error which I tried finding the solution but i am bit unlucky in solving this issue from quite sometime now.
events.js:292
throw er; // Unhandled 'error' event
^
MongoParseError: Invalid message size: 1347703880, max allowed: 67108864
at processIncomingData (/Users/rk/Desktop/workspace/project/service/node_modules/mongodb/lib/cmap/message_stream.js:118:7)
at MessageStream._write (/Users/rk/Desktop/workspace/project/service/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
at doWrite (_stream_writable.js:403:12)
at writeOrBuffer (_stream_writable.js:387:5)
at MessageStream.Writable.write (_stream_writable.js:318:11)
at Socket.ondata (_stream_readable.js:716:22)
at Socket.emit (events.js:315:20)
at addChunk (_stream_readable.js:295:12)
at readableAddChunk (_stream_readable.js:271:9)
at Socket.Readable.push (_stream_readable.js:212:10)
at TCP.onStreamRead (internal/stream_base_commons.js:186:23)
Emitted 'error' event on MessageStream instance at:
at errorOrDestroy (internal/streams/destroy.js:108:12)
at MessageStream.onerror (_stream_readable.js:752:7)
at MessageStream.emit (events.js:315:20)
at errorOrDestroy (internal/streams/destroy.js:108:12)
at onwriteError (_stream_writable.js:418:5)
at onwrite (_stream_writable.js:445:5)
at processIncomingData (/Users/rk/Desktop/workspace/project/service/node_modules/mongodb/lib/cmap/message_stream.js:117:5)
at MessageStream._write (/Users/rk/Desktop/workspace/project/service/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
[... lines matching original stack trace ...]
at Socket.Readable.push (_stream_readable.js:212:10)
Thank you for the help in advance.
I fixed this above issue by Exposing Port to mongo service in my docker-compose.yml apart from mongo-express service.
But I ran into another issue now and that is related to authentication when connecting to mongodb using nestjs. Though Mongodb Container can be accessed using compass. I will be debugging this and if required will raise a new question in SO.
I am developing API with nestjs and TypeORM connected with PostgreSQL. NestJS is using ormconfig.json file to provide database connection.
{
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "xyz",
"password": "xyz",
"database": "xyz",
"entities": ["src/**/**.entity{.ts,.js}"],
"synchronize": true
}
When in dev mode npm run start:dev everything works OK, API is responding, connected properly with database. But when I try run production build: npm run prestart:prod followed by npm run start:prod something breaks and program cannot connect to the database, that cause error:
[Nest] 12444 - 2019-04-09 22:19 [NestFactory] Starting Nest application...
[Nest] 12444 - 2019-04-09 22:19 [InstanceLoader] TypeOrmModule dependencies initialized +85ms
[Nest] 12444 - 2019-04-09 22:19 [InstanceLoader] AppModule dependencies initialized +3ms
[Nest] 12444 - 2019-04-09 22:19 [TypeOrmModule] Unable to connect to the database. Retrying (1)... +111ms
C:\_code\sensorhub\packages\api-nestjs\src\installations\models\installation.entity.ts:1
(function (exports, require, module, __filename, __dirname) { import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
^
SyntaxError: Unexpected token {
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Object.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
[Nest] 12444 - 2019-04-09 22:19 [TypeOrmModule] Unable to connect to the database. Retrying (2)... +3130ms
installation.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
#Entity()
export class InstallationEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ length: 500 })
name: string;
#Column('text')
description: string;
}
I think that code itself is correct, but there is something wrong with proper configuration.
nestjs ver.6.0.0
try this one: https://github.com/nestjs/nest/issues/184
using a dynamic ormconfig.js (instead of .json)