技術っぽいことを書いてみるブログ

PythonとかVue.jsとか技術的なことについて書いていきます。

NestJsでgRPCやってみた(Client編)

やること

NestJsでgRPCでサービスを呼び出す。

参考

  • 前回のServer編は、こちらを参照してください

ModuleでClientsModuleをインポートする

app.module.ts

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'postCode',
        transport: Transport.GRPC,
        options: {
          url: 'localhost:5000',
          package: 'postCode',
          protoPath: join(__dirname, 'proto/postCode.proto'),
        },
      },
    ]),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
  • importにて、ClientModuleをインポートする
    • ClientModuleは、registerメソッドで生成する
    • nameは、ServiceクラスでInjectする際のキーとなる
    • transportでgRPCを設定する
    • optionでターゲットのURLや.protoの情報をセットする

ServiceクラスでgRPCの呼び出しを行う

import { Injectable, OnModuleInit, Inject } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { Observable } from 'rxjs';
import { Address, PostCode } from './model';

interface SampleService {
  FindOne(data: PostCode): Observable<Address>;
}

@Injectable()
export class AppService implements OnModuleInit {
  private sampleService: SampleService;

  constructor(@Inject('postCode') private client: ClientGrpc) {}

  onModuleInit() {
    this.sampleService =
      this.client.getService<SampleService>('PostCodeService');
  }

  getHello(): Observable<Address> {
    return this.sampleService.FindOne({ id: 1234567 });
  }
}
  • interface のSampleServiceは、.protoで定義されたメソッドと同様の定義となる
  • private変数として、sampleServiceを定義する
  • constructorインジェクションで、moduleでClientsModule.registerを使用してimportしたClientをインジェクトする
  • serviceクラスは、OnModuleInitを継承し、onModuleInitメソッドにて初期化時の処理が動くようにする
    • onModuleInitで、sampleServiceのインスタンスを生成する
      • clientのgetServiceメソッドを使用して、.protoファイルで定義されたメソッドをコールできるようにする

controller

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { Address } from './model';
import { Observable } from 'rxjs';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('test')
  getTest(): Observable<Address> {
    return this.appService.getHello();
  }
}
  • 今回はRestAPI呼び出しできるように用意した

実行してみた

API Testerで実行してみた

  • うんうん、Server編のサービスの結果が返ってきているね。。

所感

  • Server編に引き続き、思ったほど難しくなく実装できました。
  • ただ、気になるのは・・・
    • 業務で使用する際には、1サービスではなく、複数サービスから情報を取得することになると、この感じだとだいぶ実装が煩雑なのと、効率悪そうな気がする。。。