dotnet-cqrs/docs/grpc-integration/grpc-reflection.md

4.8 KiB

gRPC Reflection

Enable gRPC reflection for development tools and service discovery.

Overview

gRPC reflection allows clients to discover available services and their methods at runtime without needing .proto files. This enables:

  • grpcurl - Command-line testing
  • Postman - GUI testing
  • BloomRPC - Desktop gRPC client
  • Service discovery - Dynamic client generation
  • Development - Faster iteration

Setup

Install Package

dotnet add package Grpc.AspNetCore.Server.Reflection

Enable Reflection

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();
builder.Services.AddGrpcReflection();  // Add reflection

var app = builder.Build();

app.MapGrpcService<CommandServiceImpl>();
app.MapGrpcService<QueryServiceImpl>();
app.MapGrpcReflectionService();  // Map reflection service

app.Run();

Using grpcurl

Installation

macOS:

brew install grpcurl

Windows:

choco install grpcurl

Linux:

# Download from GitHub releases
wget https://github.com/fullstorydev/grpcurl/releases/download/v1.8.9/grpcurl_1.8.9_linux_x86_64.tar.gz
tar -xvf grpcurl_1.8.9_linux_x86_64.tar.gz
sudo mv grpcurl /usr/local/bin/

List Services

grpcurl -plaintext localhost:5001 list

Output:

grpc.reflection.v1alpha.ServerReflection
myapp.CommandService
myapp.QueryService

Describe Service

grpcurl -plaintext localhost:5001 describe myapp.CommandService

Output:

myapp.CommandService is a service:
service CommandService {
  rpc CreateUser ( .myapp.CreateUserCommand ) returns ( .myapp.CreateUserResponse );
  rpc DeleteUser ( .myapp.DeleteUserCommand ) returns ( .google.protobuf.Empty );
}

Describe Message

grpcurl -plaintext localhost:5001 describe myapp.CreateUserCommand

Output:

myapp.CreateUserCommand is a message:
message CreateUserCommand {
  string name = 1;
  string email = 2;
  int32 age = 3;
}

Call Method

grpcurl -plaintext \
  -d '{"name": "John Doe", "email": "john@example.com", "age": 25}' \
  localhost:5001 \
  myapp.CommandService/CreateUser

Response:

{
  "userId": 42
}

With Metadata

grpcurl -plaintext \
  -H "Authorization: Bearer eyJhbGc..." \
  -H "X-Request-ID: abc-123" \
  -d '{"userId": 42}' \
  localhost:5001 \
  myapp.QueryService/GetUser

Using Postman

Setup

  1. Create new gRPC request
  2. Enter server URL: localhost:5001
  3. Click "Use Server Reflection"
  4. Postman discovers all services

Making Requests

  1. Select service (e.g., CommandService)
  2. Select method (e.g., CreateUser)
  3. Fill in message fields
  4. Click "Invoke"
  5. View response

Adding Headers

  1. Click "Metadata" tab
  2. Add key-value pairs:
    • Key: Authorization
    • Value: Bearer token...
  3. Click "Invoke"

Using BloomRPC

Installation

Download from: https://github.com/bloomrpc/bloomrpc

Setup

  1. Launch BloomRPC
  2. Click "+" to add server
  3. Enter address: localhost:5001
  4. Enable "Use Server Reflection"
  5. Services appear in left panel

Making Requests

  1. Select method from tree
  2. Edit JSON request
  3. Click play button
  4. View response

Production Considerations

Disable in Production

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

Conditional Registration

builder.Services.AddGrpc();

if (builder.Configuration.GetValue<bool>("EnableGrpcReflection"))
{
    builder.Services.AddGrpcReflection();
}

var app = builder.Build();

if (app.Configuration.GetValue<bool>("EnableGrpcReflection"))
{
    app.MapGrpcReflectionService();
}

With Authentication

app.MapGrpcReflectionService().RequireAuthorization("AdminOnly");

Alternatives to Reflection

Static .proto Files

Distribute .proto files to clients:

# Client downloads .proto files
curl https://api.example.com/protos/cqrs_services.proto > cqrs_services.proto

# Generate client code
protoc --csharp_out=. --grpc_out=. cqrs_services.proto

Client Libraries

Publish NuGet package with generated client code:

<ItemGroup>
  <Protobuf Include="Protos\cqrs_services.proto" GrpcServices="Client" />
</ItemGroup>
dotnet pack -c Release
dotnet nuget push MyApi.Client.1.0.0.nupkg

Best Practices

DO

  • Use reflection in development
  • Disable reflection in production (or secure it)
  • Use grpcurl for quick testing
  • Document gRPC endpoints
  • Version your services

DON'T

  • Don't expose reflection publicly without auth
  • Don't rely on reflection for production clients
  • Don't skip .proto file documentation

See Also