C# Academy · レッスン

gRPCとProtobufの基礎

.protoファイルでサービスコントラクトを定義し、Grpc.ToolsでC#コードを生成して、gRPCのトランスポートを理解します。

レッスン 1/413 ステップ

「gRPCとProtobufの基礎」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

gRPC とは

gRPC は、Google が開発した高性能で言語に依存しない RPC フレームワークです。トランスポートに HTTP/2、シリアル化形式に Protocol Buffers(Protobuf)を使用し、HTTP/1.1 上の JSON よりもはるかに高速でコンパクトです。

Protocol Buffers:IDL

サービスのコントラクトを .proto ファイルで定義します。Protobuf IDL(Interface Definition Language)は強い型付けを備えた言語中立の形式で、同じファイルから C#、Go、Python などのクライアント/サーバーコードを生成できます。

// greet.proto
syntax = "proto3";

option csharp_namespace = "GrpcService";

package greet;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

.NET での gRPC サーバーのセットアップ

dotnet new grpc を使って gRPC プロジェクトを作成します。.proto ファイルをプロジェクトに追加すると、Grpc.Tools がビルド時に C# クラスを自動生成します。

// .csproj snippet
<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>

// Program.cs
builder.Services.AddGrpc();

var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.Run();

gRPC サービスの実装

生成された基底クラスを継承し、RPC メソッドをオーバーライドします。フレームワークがシリアル化、HTTP/2 フレーミング、ルーティングを自動的に処理します。

using Grpc.Core;
using GrpcService;

public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger) => _logger = logger;

    public override Task<HelloReply> SayHello(
        HelloRequest request,
        ServerCallContext context)
    {
        _logger.LogInformation("Saying hello to {Name}", request.Name);
        return Task.FromResult(new HelloReply
        {
            Message = $"Hello, {request.Name}!"
        });
    }
}

gRPC クライアントの作成

Protobuf コンパイラーは、強く型付けされたクライアントクラスも生成します。GrpcChannel を使って接続し、ローカルメソッドと同じようにサービスを呼び出します。

// Client project: add Grpc.Net.Client package
using var channel = GrpcChannel.ForAddress("https://localhost:7042");
var client = new Greeter.GreeterClient(channel);

var reply = await client.SayHelloAsync(
    new HelloRequest { Name = "Alice" });

Console.WriteLine(reply.Message); // Hello, Alice!

Protobuf の型とフィールド番号

Protobuf メッセージの各フィールドには、一意のフィールド番号(1~536870911)があります。フィールド番号はバイナリ形式にエンコードされるため、デプロイ後に変更すると後方互換性が壊れます。決して変更しないでください。

message Product {
  int32  id          = 1;
  string name        = 2;
  double price       = 3;
  int32  stock       = 4;
  bool   is_active   = 5;
  repeated string tags = 6; // array
}

// Supported scalar types:
// int32, int64, uint32, uint64, float, double
// bool, string, bytes, enum

列挙型とネストされたメッセージ

Protobuf は列挙型とネストされたメッセージ型をサポートしています。これらを使って、サービスコントラクト内の複雑なドメインオブジェクトをモデル化します。

enum OrderStatus {
  ORDER_STATUS_UNSPECIFIED = 0;
  ORDER_STATUS_PENDING     = 1;
  ORDER_STATUS_SHIPPED     = 2;
  ORDER_STATUS_CANCELLED   = 3;
}

message Order {
  int32       id       = 1;
  OrderStatus status   = 2;
  repeated OrderLine lines = 3;
}

message OrderLine {
  int32  product_id = 1;
  int32  quantity   = 2;
  double price      = 3;
}

HTTP/2 と gRPC のトランスポート

gRPC は多重化をサポートする HTTP/2 を使用します。つまり、1 つの TCP 接続上で複数の RPC 呼び出しを同時に実行できるため、HTTP/1.1 と比べてレイテンシーと接続のオーバーヘッドを削減できます。

// gRPC requires HTTP/2
// For local dev with HTTP (not HTTPS), enable HTTP/2 cleartext:
builder.WebHost.ConfigureKestrel(opt =>
    opt.ListenLocalhost(5000, o => o.Protocols = HttpProtocols.Http2));

// Client for cleartext (dev only)
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
using var channel = GrpcChannel.ForAddress("http://localhost:5000");

StatusCode によるエラー処理

gRPC は HTTP とは異なる独自のステータスコードを使用します。Status を指定した RpcException をスローすると、型付きのエラーレスポンスをクライアントに送信できます。

public override Task<ProductReply> GetProduct(
    ProductRequest request,
    ServerCallContext context)
{
    var product = _repo.FindById(request.Id);
    if (product is null)
        throw new RpcException(
            new Status(StatusCode.NotFound, $"Product {request.Id} not found"));

    return Task.FromResult(MapToReply(product));
}

開発のための gRPC Reflection

gRPC Reflection を有効にすると、grpcurl や Postman などのツールが、.proto ファイルに直接アクセスしなくてもサービスを検出できます。

// dotnet add package Grpc.AspNetCore.Server.Reflection

builder.Services.AddGrpcReflection();

if (app.Environment.IsDevelopment())
    app.MapGrpcReflectionService();

// Now use grpcurl:
// grpcurl -plaintext localhost:5000 list
// grpcurl -plaintext localhost:5000 greet.Greeter/SayHello

実践:マイクロサービスによる商品検索

注文サービスが内部で利用する gRPC エンドポイントを公開する商品サービスです。サービス間通信の典型的なパターンです。

// product.proto
service ProductService {
  rpc GetProduct (GetProductRequest) returns (ProductResponse);
  rpc ListProducts (ListProductsRequest) returns (ListProductsResponse);
}

// Order service calls it:
public class OrderService
{
    private readonly ProductService.ProductServiceClient _products;
    public OrderService(ProductService.ProductServiceClient p) => _products = p;

    public async Task<Order> PlaceOrderAsync(int productId, int qty)
    {
        var product = await _products.GetProductAsync(
            new GetProductRequest { Id = productId });
        return new Order { ProductName = product.Name, Quantity = qty };
    }
}

確認問題

デプロイ後に既存の Protobuf フィールド番号を決して変更してはいけないのはなぜですか。

まとめ:gRPC と Protobuf の基礎

重要なポイント:

  • gRPC は HTTP/2 + Protobuf を使い、高速で強く型付けされたサービス間通信を実現します
  • サービスコントラクトを .proto ファイルで定義し、ビルド時にコードを生成します
  • フィールド番号はワイヤーエンコーディングそのものなので、決して変更または再利用しないでください
  • 生成された基底クラスを継承し、RPC メソッドをオーバーライドします
  • 型付きのエラーレスポンスには、StatusCode を指定した RpcException を使用します
  • 開発時のツール連携のために gRPC Reflection を有効にします
無料で開始

AI チューターと学ぶ C# — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
93
レッスン
346

よくある質問

「gRPCとProtobufの基礎」レッスンは無料ですか?

はい。「gRPCとProtobufの基礎」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「gRPCとProtobufの基礎」で何を学びますか?

.protoファイルでサービスコントラクトを定義し、Grpc.ToolsでC#コードを生成して、gRPCのトランスポートを理解します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「gRPCとProtobufの基礎」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. gRPCとProtobufの基礎
  2. UnaryとサーバーストリーミングRPC
  3. クライアントと双方向ストリーミング
  4. デッドライン、キャンセルとインターセプター
← C# Academyに戻る