やること
- NestJsでgPRCのサービスを定義する
事前準備
gPRCを使うための関連ライブラリをインストールする。
npm i @nestjs/microservices npm i @grpc/grpc-js @grpc/proto-loader
.protoの定義
gRPCのAPI定義を定義するprotoファイルを定義します。
proto/postCode.proto
syntax = "proto3"; package postCode; service PostCodeService { rpc FindOne (PostCode) returns (Address) {} } message PostCode { int32 id = 1; } message Address { int32 id = 1; string prefectures = 2; string address1 = 3; string address2 = 4; }
- syntax : バージョンの指定
- package:パッケージを指定する
- service:サービスを定義する
- rpc:サービス内のメソッドになる部分を定義する
- 上記の例だと、PostCodeServiceにFineOneメソッドがあり、引数はPostCodeという型(インターフェース)で受取り、Addressという型を返すよという内容
- rpc:サービス内のメソッドになる部分を定義する
- message:メッセージを定義する。型になる部分
main.tsの定義
nestjsのmain.tsでマイクロサービスを定義します。
main.ts
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { join } from 'path'; import { GrpcOptions, Transport } from '@nestjs/microservices'; async function bootstrap() { const app = await NestFactory.createMicroservice<GrpcOptions>(AppModule, { transport: Transport.GRPC, options: { url: 'localhost:5000', package: 'postCode', protoPath: join(__dirname, 'proto/postCode.proto'), }, }); await app.listen(); } bootstrap();
NestFactory.createMicroservice
でNestJsがマイクロサービスとして起動することを定義するtransport: Transport.GRPC,
にすることで、gRPCで通信しますよと定義するoptions
で、作成したprotoファイルへのパスとURLを設定する
controllerの定義
import { Controller, Get } from '@nestjs/common'; import { Address, PostCode } from './model'; import { GrpcMethod } from '@nestjs/microservices'; @Controller() export class AppController { @GrpcMethod('PostCodeService') findOne(request: PostCode, metadata: any): Address { return { id: 6730000, prefectures: '兵庫県', address1: '三木市', address2: '××町', }; } }
- コントローラーのメソッドに
@GrpcMethod
を付与する。PostCodeService
と定義することで、protoファイルのPostCodeService と紐付く
- protoファイルのPostCodeService と紐付いたので、メソッド名はprotoファイルの定義と同様
FindOne
となる - FineOneメソッドは、protoファイルを参照すると、
PostCode
型になり、Address
型を返却するように定義されているので、メソッドの定義も同様にする- ただし、当然protoファイルのmessageはtypescriptのインターフェースとしてそのまま使えないので、interfaceを別途定義する必要あり
- ※ここでは、適当に値を返すようにしています。
インターフェースの定義
リクエストとレスポンスのinterfaceをprotoファイルに合わせて定義する。
model.ts
export interface PostCode { id: number; } export interface Address { id: number; prefectures: string; address1: string; address2: string; }
実行してみる
今回は呼び出し元のプロジェクトをまだ作成していないので、
ツールを使用して実行してみます。
仕様したツールは、こちらです。 github.com
まずは、npm run start:dev
でNestを起動
[10:31:09] Starting compilation in watch mode... [10:31:10] Found 0 errors. Watching for file changes. [Nest] 13252 - 2023/08/05 10:31:11 LOG [NestFactory] Starting Nest application... [Nest] 13252 - 2023/08/05 10:31:11 LOG [InstanceLoader] AppModule dependencies initialized +7ms [Nest] 13252 - 2023/08/05 10:31:11 LOG [NestMicroservice] Nest microservice successfully started +139ms
BloomRPCで実行。
という感じで、実行できました。
所感
意外と簡単にできました。
次回は、このgRPCを呼び出すnestjsを用意してみます。
こうした方がええでという意見がありましたら、コメントをお願いします。