构建Nestjs微服务

本文介绍了如何在Nest框架中使用微服务架构,包括创建项目、配置微服务依赖、设置仓库服务与主服务之间的通信方式,以及使用CLI工具进行操作和通过Postman测试接口。重点讲解了如何使用TCP传输和MessagePattern装饰器来实现请求-响应和事件驱动的消息传递。
摘要由CSDN通过智能技术生成

在 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查询图书

NestJS是一个基于TypeScript和Node.js的现代全功能JavaScript框架。它专为构建高性能、模块化的API而设计。为了启动一个NestJS项目并运行微服务,你需要首先确保已经安装了Node.js环境。 ### 安装 NestJS 如果你还没有安装 `@nestjs/cli` 工具,可以使用以下命令全局安装: ```bash npm install -g @nestjs/cli ``` 或者如果你更倾向于使用Yarn: ```bash yarn global add @nestjs/cli ``` ### 创建新项目 创建一个新的NestJS项目,可以在终端输入以下命令,并按照提示操作: ```bash nest new my-project-name cd my-project-name ``` 这里 `"my-project-name"` 应该替换为你想要的项目名称。 ### 启动微服务 在创建完项目并且配置好依赖之后,你可以通过以下命令启动你的微服务: ```bash npm start:dev 或 yarn start:dev ``` 这里的 `start:dev` 表示以开发模式启动应用,这意味着应用会自动重启每次文件更改发生时,非常适合于开发阶段。 如果想以生产模式部署,使用: ```bash npm run start 或 yarn start ``` 这将启动一个无刷新机制的应用,适合于生产环境。 ### 相关问题: 1. **如何配置NestJS项目?** 答案通常涉及设置环境变量、数据库连接、中间件、路由等。NestJS官方文档提供了详细的指导和示例。 2. **NestJS项目的结构是什么样的?** NESTJS项目通常包括公共库、服务层、控制器、提供者等多个部分,每个部分都服务于特定目的,如基础业务逻辑、HTTP API、依赖注入等。 3. **如何处理错误和异常在NestJS中?** NESTJS提供了强大的错误处理机制,包括自定义异常处理器、中间件等,可以帮助开发者优雅地处理各种类型的错误情况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值