构建Nestjs微服务

在 Nest 中,微服务本质上是一个使用与 HTTP 不同的传输层的应用。

Nest 支持多种内置的传输层实现,称为传输器,它们负责在不同的微服务实例之间传输消息。大多数传输器本身支持请求-响应和基于事件的消息样式。Nest 将每个传输器的实现细节抽象为请求-响应和基于事件的消息传递的规范接口。

1. 创建项目

使用 cli 创建项目

nest new bookstore

2. 创建微服务

进入目录后,使用 cli 创建微服务

nest g app warehouse

生成后的目录

安装微服务和配置的依赖包

pnpm i @nestjs/microservices
pnpm i @nestjs/config

创建 .env 文件,配置微服务的 host 和 port

BOOKSTORE_SERVICE_HOST=127.0.0.1
BOOKSTORE_SERVICE_PORT=3001

3. 设置微服务

3.1 修改 warehouse 模块

修改 apps/warehouse/warehouse.module.ts 文件,把config模块引入

import { Module } from '@nestjs/common';
import { WarehouseController } from './warehouse.controller';
import { WarehouseService } from './warehouse.service';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
  controllers: [WarehouseController],
  providers: [WarehouseService],
})
export class WarehouseModule {}

3.2 修改 warehouse 主文件

修改 apps/warehouse/main.ts 文件,先创建app上下文,获取到config的配置中微服务的 host 和port 值。使用 createMicroservice 创建微服务,设置TCP传输和参数

import { NestFactory } from '@nestjs/core';
import { WarehouseModule } from './warehouse.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { ConfigService } from '@nestjs/config';

async function bootstrap() {
  const appContext = await NestFactory.createApplicationContext(
    WarehouseModule,
  );
  const configService = appContext.get(ConfigService);
  const host = configService.get<string>('BOOKSTORE_SERVICE_HOST');
  const port = configService.get<number>('BOOKSTORE_SERVICE_PORT');

  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    WarehouseModule,
    {
      transport: Transport.TCP,
      options: {
        host: host,
        port: port,
      },
    },
  );
  await app.listen();
}
bootstrap();

3.3 修改 warehouse 控制器

增加 newBook 添加图书, getBook 通过ID查询图书, getBooks 查询所有图书,3个方法

并使用 MessagePattern 装饰器,启用请求-响应消息类型

import { Controller } from '@nestjs/common';
import { WarehouseService } from './warehouse.service';
import { MessagePattern } from '@nestjs/microservices';
import { bookDto } from 'dto/book.dto';

@Controller()
export class WarehouseController {
  constructor(private readonly warehouseService: WarehouseService) {}

  @MessagePattern({ cmd: 'add_book' })
  addBook(book: bookDto) {
    return this.warehouseService.addBook(book);
  }

  @MessagePattern({ cmd: 'get_book' })
  getBook(id: string) {
    return this.warehouseService.getBook(id);
  }

  @MessagePattern({ cmd: 'get_books' })
  getBooks() {
    return this.warehouseService.getAllBooks();
  }
}

补充一个 book.dto.ts 文件

export class bookDto {
  id: string;
  title: string;
  author: string;
  release_date: string;
}

3.4 修改 warehouse 服务

import { Injectable } from '@nestjs/common';
import { bookDto } from 'dto/book.dto';

const bookStore: bookDto[] = [];

@Injectable()
export class WarehouseService {
  addBook(book: bookDto) {
    book.id = bookStore.length + 1 + '';
    bookStore.push(book);
    return book;
  }

  getBook(id: string) {
    return bookStore.find((book: bookDto) => book.id === id);
  }

  getAllBooks() {
    return bookStore;
  }
}

4. 设置主服务

4.1 修改 bookstore 模块

添加 config 模块和微服务的 provide

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  imports: [ConfigModule.forRoot()],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: 'WAREHOUSE_SERVICE',
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        return ClientProxyFactory.create({
          transport: Transport.TCP,
          options: {
            host: configService.get('BOOKSTORE_SERVICE_HOST'),
            port: configService.get('BOOKSTORE_SERVICE_PORT'),
          },
        });
      },
    },
  ],
})
export class AppModule {}

4.2 修改 bookstore 控制器

注入微服务的service,并增加3个方法

getAllBooks  查询所有图书

getBookById  通过ID查询图书

addBook  添加图书

import { Body, Controller, Get, Inject, Param, Post } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { bookDto } from 'dto/book.dto';
import { Observable } from 'rxjs';

@Controller('bookstore')
export class AppController {
  constructor(
    @Inject('WAREHOUSE_SERVICE') private warehouseService: ClientProxy,
  ) {}

  @Get()
  getAllBooks(): Observable<bookDto[]> {
    return this.warehouseService.send({ cmd: 'get_books' }, {});
  }

  @Get(':id')
  getBookById(@Param('id') id: string): Observable<bookDto | undefined> {
    return this.warehouseService.send({ cmd: 'get_book' }, id);
  }

  @Post()
  addBook(@Body() book: bookDto): Observable<bookDto> {
    return this.warehouseService.send({ cmd: 'add_book' }, book);
  }
}

5. 启动服务

启动微服务

nest start warehouse --watch

启动主服务

nest start bookstore --watch

6. 使用postman调用

6.1 添加图书接口

6.2 查询所有图书接口

6.3 通过ID查询图书

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
NestJS是一个用于构建高效、可扩展的Node.js服务器端应用程序的开发框架。它提供了一组强大的工具和模块,使得开发者可以快速构建可维护、可测试的应用程序。 在NestJS中,使用SSE(Server-Sent Events)来实现服务器向客户端推送事件。SSE是一种基于HTTP的轻量级协议,允许服务器向客户端推送事件,而无需客户端发送请求。 在NestJS中使用SSE非常简单,只需要在控制器中返回一个EventSource对象即可,如下所示: ``` import { Controller, Get } from '@nestjs/common'; @Controller() export class AppController { @Get('events') events(): any { const eventSource = new EventSource('/stream'); return { eventSource }; } } ``` 上面的代码创建了一个/events路由,当客户端访问该路由时,将返回一个包含EventSource对象的响应。客户端可以使用EventSource对象来监听服务器推送的事件。 接下来,我们需要创建一个/stream路由,用于向客户端推送事件。可以使用NestJS提供的@EventPattern装饰器来实现该功能,如下所示: ``` import { Controller, Get } from '@nestjs/common'; import { EventPattern } from '@nestjs/microservices'; @Controller() export class AppController { @Get('events') events(): any { const eventSource = new EventSource('/stream'); return { eventSource }; } @EventPattern('newMessage') async handleNewMessage(data: any) { const message = JSON.stringify(data); const event = `data: ${message}\n\n`; eventSource.write(event); } } ``` 上面的代码中,@EventPattern('newMessage')装饰器表示该方法会处理名为newMessage的事件。在handleNewMessage方法中,我们将接收到的数据转换为字符串,并通过eventSource对象向客户端推送事件。 相关问题: 1. SSE和WebSocket有什么区别? 2. 在NestJS中如何处理WebSocket连接? 3. 如何在NestJS中处理异步事件?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值