Гибридное приложение в Nest
Два окна терминала усложняют разработку: HTTP и TCP слушатели логически относятся к одному приложению, но живут в разных процессах и дублируют модуль.
Гибридное приложение
создают через обычный
NestFactory.create,
затем подключают микросервис
методом connectMicroservice
с тем же транспортом TCP.
Перед listen для страниц
вызывают startAllMicroservices,
чтобы канал сообщений успел
открыться в том же процессе NodeJS.
Один модуль может содержать
и HTTP контроллер, и обработчик
шаблонов.
Покажем на примере постов:
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module.js';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.connectMicroservice<MicroserviceOptions>({
transport: Transport.TCP,
options: {
host: '127.0.0.1',
port: 3001,
},
});
await app.startAllMicroservices();
await app.listen(3000);
}
bootstrap();
Один класс обслуживает и страницу, и запрос по каналу:
import { Body, Controller, Get, Post } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { PostService } from './post.service.js';
@Controller('posts')
export class PostController {
postService: PostService;
constructor(postService: PostService) {
this.postService = postService;
}
@Get()
list() {
return this.postService.list();
}
@Post()
create(@Body('title') title: string) {
return this.postService.add(title);
}
@MessagePattern({ cmd: 'list_posts' })
listByMessage() {
return this.postService.list();
}
@MessagePattern({ cmd: 'add_post' })
addByMessage(@Payload() data: { title: string }) {
return this.postService.add(data.title);
}
}
Сервис хранит массив заголовков в памяти:
import { Injectable } from '@nestjs/common';
@Injectable()
export class PostService {
posts: { title: string }[] = [];
list() {
return this.posts;
}
add(title: string) {
const post = { title };
this.posts.push(post);
return post;
}
}
Зарегистрируем классы в корневом модуле:
import { Module } from '@nestjs/common';
import { PostController } from './post.controller.js';
import { PostService } from './post.service.js';
@Module({
controllers: [PostController],
providers: [PostService],
})
export class AppModule {}
Соберите гибридное приложение
работников: подключите TCP канал,
запустите микросервисы до
страниц и опишите WorkerController
с HTTP маршрутами и приёмом
сообщений через WorkerService.