フロントエンドとの連携が最大限ラクになる gRPCのスキーマ設計
はじめに
弊社で開発中のマーケティングSaaS NeX-Rayのバックエンド開発ではgRPCを採用しています。
gRPCは、Googleによって開発されたリモートプロシージャコール(RPC)システムで、HTTP/2を使用した効率的な通信の実現や、スキーマ駆動開発が可能であることがメリットとなっています。
本記事では、Nex-RayにおけるgRPCのスキーマ設計を解説します。
スキーマ設計
gRPCのスキーマ定義は、Protocol Buffers(protobuf)と呼ばれるインタフェース定義言語(IDL)によって記述されます。
例えば、protobufは、以下のように定義されます。
service GatewayService {
rpc Register(SampleRequest) returns (SampleResponse) {}
}
message RegisterRequest {
string name = 1;
}
message RegisterResponse {
string id = 1;
}
GatewayserviceのRegisterは、RegisterRequestを受け取り、RegisterResponseを返すようなRPCとなっています。
NeX-Rayでは、バックエンドのマイクロサービス単位で、以下のようにgRPCのサービスを切り分け定義しています。
- フロントエンドで利用するRPCを定義するGatewayService
- バックエンドで利用するRPCを定義するServerService
ディレクトリ構成は、次の通りです。
└── proto
├── microService-1
│ └── v1
│ ├── microService-1-gateway.proto // GatewayServiceを定義
│ ├── microService-1-server.proto // ServerServiceを定義
│ └── microService-1-message.proto // Gateway/Serverで共有するメッセージを定義
└── microService-2
└── v1
├── microService-2-gateway.proto
├── microService-2-server.proto
└── microService-2-message.proto
:
:
:
BFFとgRPCサーバーの実装概要
NeX-Rayでは、BFFとしてGraphQL Meshを採用しています。
GraphQL Meshとは、複数のWebAPIを結合して、1つのGraphQLサービスにすることができるGraphQL Gatewayのライブラリです。
こちらについては、下記の記事で詳しく解説しています。
Graphql Meshは、gRPCをサポートしているので、protobufのスキーマ定義からフロントエンドに提供するGraphQLスキーマを自動生成してくれます。バックエンドでは、Protocol Buffersにより定義されたスキーマからコードを自動生成し、GatewayServiceおよびServerServiceのgRPCサーバーをそれぞれ実装しています。
これによりフロントエンド・バックエンド間でのメソッド定義の共有が容易となっており、また、GatewayServiceおよびServerServiceとして分離することで、フロントエンド・バックエンドそれぞれの仕様変更に柔軟に対応できる構成となっています。
運用面では、gRPCのスキーマ定義を修正するたびにGraphQL Meshでインポートするgrpcのスキーマ定義のバージョンアップが必要なため、GraphQL Mesh側のバージョンアップを失念してしまうと、BFFとバックエンドでgRPCのスキーマ定義がズレてしまうことがありました。
慣れてしまえば問題ない程度ですが、改善策を模索しているところです。
まとめ
NeX-RayにおけるgRPCのスキーマ設計を解説してきましたが、いかがだったでしょうか?
NeX-Rayでは、gRPCのスキーマ定義から、フロントエンド・バックエンドの関心を分離することで、仕様変更に強い構成を実現しています。また、gRPCにGraphql Meshを組み合わせることで、メソッド定義の共有やGraphQLスキーマの提供を容易にしています。
Nex-Rayの開発に少しでも興味を持っていただけると幸いです。
フィシルコムのテックブログです。マーケティングSaaSを開発しています。 マイクロサービス・AWS・NextJS・Golang・GraphQLに関する発信が多めです。 カジュアル面談はこちら(ficilcom.notion.site/bbceed45c3e8471691ee4076250cd4b1)から
Discussion