# 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 ```bash dotnet add package Grpc.AspNetCore.Server.Reflection ``` ### Enable Reflection ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddGrpc(); builder.Services.AddGrpcReflection(); // Add reflection var app = builder.Build(); app.MapGrpcService(); app.MapGrpcService(); app.MapGrpcReflectionService(); // Map reflection service app.Run(); ``` ## Using grpcurl ### Installation **macOS:** ```bash brew install grpcurl ``` **Windows:** ```powershell choco install grpcurl ``` **Linux:** ```bash # 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 ```bash grpcurl -plaintext localhost:5001 list ``` **Output:** ``` grpc.reflection.v1alpha.ServerReflection myapp.CommandService myapp.QueryService ``` ### Describe Service ```bash 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 ```bash 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 ```bash grpcurl -plaintext \ -d '{"name": "John Doe", "email": "john@example.com", "age": 25}' \ localhost:5001 \ myapp.CommandService/CreateUser ``` **Response:** ```json { "userId": 42 } ``` ### With Metadata ```bash 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 ```csharp if (app.Environment.IsDevelopment()) { app.MapGrpcReflectionService(); } ``` ### Conditional Registration ```csharp builder.Services.AddGrpc(); if (builder.Configuration.GetValue("EnableGrpcReflection")) { builder.Services.AddGrpcReflection(); } var app = builder.Build(); if (app.Configuration.GetValue("EnableGrpcReflection")) { app.MapGrpcReflectionService(); } ``` ### With Authentication ```csharp app.MapGrpcReflectionService().RequireAuthorization("AdminOnly"); ``` ## Alternatives to Reflection ### Static .proto Files Distribute .proto files to clients: ```bash # 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: ```xml ``` ```bash 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 - [gRPC Integration Overview](README.md) - [Getting Started](getting-started-grpc.md) - [gRPC Clients](grpc-clients.md) - [grpcurl Documentation](https://github.com/fullstorydev/grpcurl)