使用 Dapr JS SDK 讓 Nest.js 集成 Dapr

  • 2022 年 6 月 18 日
  • 筆記

image

Dapr 是一個可移植的、事件驅動的運行時,它使任何開發人員能夠輕鬆構建出彈性的、無狀態和有狀態的應用程式,並可運行在雲平台或邊緣計算中,它同時也支援多種程式語言和開發框架。

Dapr 中文手冊://docs.dapr.io/zh-hans/

文件結構

Dapr JS SDK

創建包含我們的 NestJS 項目的文件結構:

src/
    main.ts             
    app.module.ts       
    config/config.ts    
    dapr/
        dapr.module.ts  
        dapr.service.ts 

創建 Nest Dapr 模組

創建文件結構後,我們可以配置我們的模組並使其可用於 NestJS

src/dapr/dapr.module.ts

import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { DaprService } from "./dapr.service";

@Module({
    imports: [ ConfigModule ],
    controllers: [ ],
    providers: [ DaprService ],
    exports: [ DaprService ]
})
export class DaprModule {}

上面的程式碼將利用 Config 模組(我們稍後將使用它來將配置注入我們的服務)以及我們將創建的包含 Dapr JS SDK 方法的 Dapr 服務。

最後,在 app.module.ts 文件中註冊這個模組:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import configuration from '../config/config';
import { DaprModule } from './dapr/dapr.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
    DaprModule
  ],
  controllers: [],
  providers: [],
})
export class AppModule;

src/dapr/dapr.service.ts

現在我們已經註冊了我們的模組,讓我們創建幫助我們訪問 Dapr JS SDK 的服務類:

import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { DaprClient } from 'dapr-client';

@Injectable()
export class DaprService {
  daprClient: DaprClient;
  private readonly logger = new Logger(DaprService.name);

  constructor(
    private readonly configService: ConfigService
  ) {
    const daprHost = this.configService.get<string>('third_party.dapr.host');
    const daprPort = this.configService.get<string>('third_party.dapr.port');

    this.logger.log(`Initializing DaprClient("${daprHost}", ${daprPort})`);
    this.daprClient = new DaprClient(daprHost, daprPort);
  }
}

如您所見,我們在此處訪問 third_party.dapr.hostthird_party.dapr.port,它們從 config/config.ts 文件中提取資訊。所以繼續使用以下配置:

export default () => ({
  third_party: {
    dapr: {
      host: process.env.DAPR_SIDECAR_HOST || '127.0.0.1',
      port: process.env.DAPR_SIDECAR_PORT || '3500',
    }
  },
});

使用 Nest 模組

現在我們創建了我們的模組,我們可以將它導入到我們的任何 Nest 模組中(在 imports: [ DaprModule ]下添加它)並開始使用它。

import { Controller, Get, HttpCode, Req, Logger } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { DaprService } from '../dapr/dapr.service';

@Controller('demo')
@ApiTags('demo')
export class DemoController {
  private readonly logger = new Logger(DemoController.name);

  constructor(
    private readonly daprService: DaprService,
  ) { }

  @Get('/')
  @HttpCode(200)
  async demo(@Req() req): Promise<void> {
    await this.daprService.daprClient.binding.send(`my-component`, "create", { hello: "world" });
 }

使用 Dapr 啟動 Nest

為了開始這一切,我們現在可以使用 dapr run 命令,它會在其中創建包含 Dapr 的進程。

dapr run --app-id my-application --app-protocol http --app-port 50001 --dapr-http-port 3500 --components-path ./components npm run start