HOME > ソフテックだより > 第485号(2025年11月5日発行) 技術レポート「gRPCの特徴と実装例の紹介」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ

「ソフテックだより」では、みなさまのご意見・ご感想を募集しています。ぜひみなさまの声をお聞かせください。


ソフテックだより 第485号(2025年11月5日発行)
技術レポート

「gRPCの特徴と実装例の紹介」

1. はじめに

近年まで、.NETアプリケーション同士の通信にはWCF(Windows Communication Foundation)が広く使われてきました。
WCF は、サービス指向アプリケーションを構築するためのフレームワークです。 WCFを利用した通信では、あるサービスエンドポイントから別のサービスエンドポイントに非同期メッセージとしてデータを送信できます。 このメッセージはXML形式で表現され、実際には「単一の文字」「単語」と同じくらいシンプルなものです。
WCFは多様な通信プロトコルに対応し、柔軟な設計が可能なフレームワークですが、一方で設定の複雑さやWindows依存やXMLベース通信によるパフォーマンスの限界などの課題もありました。
そのような背景の中で登場したのがgRPC(Google Remote Procedure Call)です。
Googleが開発したgRPCは、軽量・高速・クロスプラットフォーム対応の通信技術です。 HTTP/2とProtocol BuffersをベースとしたgRPCでは、WCFのような複雑な設定をせずに通信を行うことができます。
本記事では、gRPCの特徴やメリット・デメリットを紹介し、サンプルのアプリケーションを用いてgRPCの実装方法について解説します。

2. gRPCとは

gRPCは、Googleが開発した高性能なリモートプロシージャコール(RPC)フレームワークで、離れたコンピューター同士がまるで関数を呼び出すように通信できる仕組みを提供します。 オープンソースとして公開されており、誰でもコードを閲覧・利用・カスタマイズすることが可能です。
また、C#、Java、Pythonなど多くのプログラミング言語に対応しており、クロスプラットフォーム環境でも柔軟に利用できます。
gRPCの通信には、Googleが開発したProtocol Buffersというバイナリ形式が使われており、XMLなどのテキスト形式に比べてデータがコンパクトで処理が高速です。 これにより、通信の負荷が軽減され、軽量かつ効率的なデータのやり取りが可能になります。 さらに、通信はHTTP/2をベースとしており、多重化やストリーミングなどの機能を活用することで、より高速で安定した通信が実現されています。
開発者は、通信の要求と応答を.protoファイルで定義することで、必要なコードを自動生成できるため、複雑な通信処理を手書きする必要がありません。
上記の特徴を踏まえ、gRPCを利用することで得られるメリットと注意すべきデメリットについて紹介します。

2-1. gRPC利用のメリット

  • 高速で軽量な通信
    gRPCのProtocol Buffersはバイナリ形式のため、WCFのXMLベースの通信よりも高速でデータ量も少なく通信を行うことができます。 その結果、アプリの反応速度やサーバーの負担、通信コストの面でパフォーマンスが向上します。

  • クロスプラットフォーム対応
    gRPCはWindows以外のLinuxやmacOSなど複数のOSに対応しており、共通のAPIと通信様式に基づいて実装できます。 これにより、異なるOS上で動作するアプリケーション同士でも通信を行うことができます。

  • コードの自動生成
    .protoファイルからクライアントとサーバー両方のコードが自動生成されます。 クライアントとサーバーが同じ.protoファイルをもとにコードを生成するため、関数名などの定義が常に一致し、通信時の不整合によるバグを防ぐことができます。 またAPIの仕様が変更されても、.protoファイルを更新するだけで関連するコードが一貫して更新されるためメンテナンスを効率的に行うことが可能です。

  • 多言語対応
    .protoファイルから複数の開発言語向けにコードを自動生成できます。また、サーバーとクライアントが異なる言語でも問題なく通信が可能です。 例えばサーバーがC#で、クライアントがPythonで書かれていても通信を行うことができます。

  • リアルタイムの通信
    gRPCでは、ストリーミング通信ができるので、クライアントとサーバーがリアルタイムでデータをやり取りができます。 今回ご紹介するサンプルでは、クライアントからのリクエストに対してサーバーが単一のレスポンスを返す形式ですが、 クライアント・サーバーの双方向のデータの送信や連続したデータの送信を行うことも可能です。

2-2. gRPC利用のデメリット

  • HTTP/2の制約
    WCFは複数の通信プロトコルに対応していましたが、gRPCはHTTP/2に依存しているため、一部の古い環境やプロキシでは動作しないことがあります。

  • ブラウザからの呼び出し
    gRPCはHTTP/2という通信方式とProtocol Buffersを使用しているため、通常のブラウザではそのまま使うことができません。 そのためブラウザから直接利用する場合は別の方法(gRPC-Web + プロキシ(Envoy))を使う必要があります。

3. gRPCの実装

vgRPCを実装するにあたって事前に以下の準備が必要です。

  • .protoファイルの作成(通信仕様の定義)
  • クライアントアプリの設定(gRPC通信の呼び出し側)
  • サーバーアプリの設定(gRPC通信の受け側)

本章では、これらの準備についてサンプルのプロジェクトを用いて順を追って説明します。構成図は下記の通りです。


図1. 構成図

また使用言語、開発環境は下記の通りです。
・言語:C#
・開発環境:.NET 8.0

3-1. .protoファイルの作成

gRPCサービスを利用する場合、クライアントアプリとサーバーアプリで同一の.protoファイルを共有する必要があります。
.protoファイルにはバージョンの定義やRPCメソッドなどを記述します。.protoファイルで定義できるデータ型は下記の表のとおりです。

表1. .protoファイルで定義可能なデータ型

データ型 デフォルト値 補足
string 空文字  
bytes 空配列  
bool False  
数値(int, floatなど) 0  
enum 最初に定義された値  
message null データ構造を定義するための基本単位。
入れ子構造にして定義することも可能
repeated 空配列 リストとして定義することが可能。

.protoファイルのサンプルは下記の通りです。

・.protoファイルのサンプル

syntax = "proto3";

option csharp_namespace = "MessageService";

// -------------------------------------------------------------
// RPCメソッド定義
service MessageService {
	// 挨拶取得
	rpc SendMessageResponse(Request_Message) returns (Response_Message);
}

// -------------------------------------------------------------
// 挨拶リクエストメッセージ

// 要求種別コード
enum RequestCode{
	Morning = 0;
	Afternoon = 1;
	Evening = 2;
}

// 挨拶リクエストメッセージ
message Request_Message{
	// 要求種別コード
	RequestCode Req_Code = 1;
}

// -------------------------------------------------------------
// 挨拶レスポンスメッセージ
message Response_Message{
	// 挨拶メッセージ
	string Res_Message = 1;
}

3-2. サーバー側の設定

サーバーとなるアプリの設定はパッケージのインストール、.protoファイルの設定、サーバーコードの作成の3点を行います。

3-2-1. パッケージインストール

NuGetで下記の3つのパッケージをインストールします。

  • Google.Protobuf
  • Grpc.Core
  • Grpc.Tools

3-2-2. .protoファイル設定

Protosフォルダを.csprojファイルと同階層に作成し、このフォルダ内に3-1で作成した.protoファイルを格納します。
その後、.csprojファイルに下記のコードを記述し、.protoファイルの定義を追加します。

・サーバーアプリ .csprojファイル追記コード

<ItemGroup>
	<Protobuf Include=”Protos\*.proto” GrpcServices=”Server” />
</ItemGroup>

3-2-3. サーバーコード作成

gRPC通信では、サーバーアプリがクライアントからのリクエストを受け取り、指定された処理を実行して結果を返します。 .protoファイルの定義をもとに、サーバー側のコードが自動生成されるため、このコードを使って簡単に通信処理を記述できます。

・サーバーコード(クラス実装)

// 自動生成されたクラスを継承して、サーバー側処理内容を実装
public class ServiceIF : MessageService.MessageServiceBase
{ 
    public override Task<Response_Message> SendMessageResponse(Request_Message request, ServerCallContext context)
    {
       // 処理結果の生成
       var response = new Response_Message();

       if (request.ReqCode == RequestCode.Morning)
       {
                  response.ResMessage = "Good Morning!";
       }
       else if (request.ReqCode == RequestCode.Afternoon)
       {
                  response.ResMessage = "Good Afternoon!";
       }
       else if (request.ReqCode == RequestCode.Evening)
       {
              response.ResMessage = "Good Evening!";
       }

       // クライアントへ応答送信
       return Task.FromResult(response);
    }
}

・サーバーコード(インスタンスの初期化)

// サービス処理インスタンス作成
gRPC_Server = new Server()
{
    Services = { MessageService.BindService(new ServiceIF()) },
    Ports = { new ServerPort("127.0.0.1", 30001, ServerCredentials.Insecure) }
};

// サービス処理開始
gRPC_Server.Start();

3-3. クライアント側の設定

クライアントとなるアプリではパッケージのインストールと.protoファイルの設定、クライアントコードの作成を行います。

3-2-1. パッケージインストール

サーバーアプリと同様に、NuGetで下記の3つのパッケージをインストールします。

  • Google.Protobuf
  • Grpc.Core
  • Grpc.Tools

3-2-2. .protoファイル設定

こちらもサーバーアプリと同様に、Protosフォルダを.csprojファイルと同階層に作成し、このフォルダ内に3-1で作成した.protoファイルを格納します。その後、.csprojファイルに下記のコードを記述し、.protoファイルの定義を追加します。

・クライアントアプリ .csprojファイル追記コード

<ItemGroup>
	<Protobuf Include=”Protos\*.proto” GrpcServices=”Client” />
</ItemGroup>

3-2-3. クライアントコード作成

gRPCでは通信仕様を.protoで定義します。クライアントアプリもサーバーアプリと同様にこのファイルをもとに、クライアント側のコードが自動生成されるため、このコードを使って簡単に通信処理を記述できます。

・クライアントコード

// gRPCインスタンス作成
gRPC_Channel = new Grpc.Core.Channel( _IPAddress, _PortNumber, ChannelCredentials.Insecure);
gRPC_Client = new MessageService.MessageService.MessageServiceClient(gRPC_Channel);

// 要求データ作成
Request_Message req = new Request_Message(); 
req. Req_Code = RequestCode.Morning;

// gRPCメソッド 呼び出し
Response_Message res = gRPC_Client. SendMessageResponse();

4. おわりに

gRPCは、異なるプラットフォームやアプリケーション間で効率的かつ高速に通信できる仕組みであり、現代のシステム開発において非常に有用です。基本的な構成や使い方を理解すれば、アプリケーション開発にとても役立ちます。ただしgRPCの導入を検討する際は既存のシステム構成や通信要件を踏まえて選定することが重要です。
今回のgRPCの基本的な仕組みやメリット・デメリットの紹介を通して、プロジェクトに合った技術選定の一助になれば幸いです。

(R.K.)


関連ページへのリンク

関連するソフテックだより

「ソフテックだより」では、みなさまのご意見・ご感想を募集しています。ぜひみなさまの声をお聞かせください。

ページTOPへ