# Choosing HTTP vs gRPC Understand when to use HTTP, gRPC, or both protocols for your application. ## Quick Decision Guide | Scenario | Recommendation | |----------|---------------| | Public API | ✅ HTTP | | Web browser clients | ✅ HTTP | | Mobile apps (REST) | ✅ HTTP | | Microservices (internal) | ✅ gRPC | | High-performance APIs | ✅ gRPC | | Low-latency requirements | ✅ gRPC | | Need both internal & public | ✅ Both (Dual Protocol) | | Existing REST clients | ✅ HTTP | | .NET-to-.NET communication | ✅ gRPC | ## HTTP (Minimal API) ### What It Is HTTP integration uses ASP.NET Core Minimal API to expose commands and queries as REST endpoints. ### When to Use ✅ **Best for:** - Public APIs - Web browser clients (JavaScript, React, Vue, etc.) - Mobile apps expecting REST - Third-party integrations - Developer-friendly exploration (Swagger) - Simple authentication (API keys, JWT) ### Pros - ✅ **Universal compatibility** - Works everywhere (browsers, curl, Postman) - ✅ **Human-readable** - JSON payloads are easy to debug - ✅ **Swagger/OpenAPI** - Automatic API documentation - ✅ **Caching** - HTTP caching headers work out of the box - ✅ **Familiar** - Developers know REST - ✅ **Tooling** - Excellent debugging and testing tools ### Cons - ❌ **Lower performance** - Text-based JSON vs binary Protocol Buffers - ❌ **Larger payloads** - JSON is verbose compared to binary - ❌ **No streaming** - Single request-response (without SSE/WebSockets) - ❌ **Manual client code** - No automatic client generation ### Example Setup ```csharp var builder = WebApplication.CreateBuilder(args); // Register CQRS builder.Services.AddSvrntyCQRS(); builder.Services.AddDefaultCommandDiscovery(); builder.Services.AddDefaultQueryDiscovery(); // Register handlers builder.Services.AddCommand(); builder.Services.AddQuery(); // Add Swagger (optional) builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Map HTTP endpoints app.UseSvrntyCqrs(); // Enable Swagger app.UseSwagger(); app.UseSwaggerUI(); app.Run(); ``` ### Usage ```bash # Commands (POST only) curl -X POST http://localhost:5000/api/command/createUser \ -H "Content-Type: application/json" \ -d '{"name":"Alice","email":"alice@example.com"}' # Queries (GET or POST) curl "http://localhost:5000/api/query/getUser?userId=1" curl -X POST http://localhost:5000/api/query/getUser \ -H "Content-Type: application/json" \ -d '{"userId":1}' ``` ## gRPC ### What It Is gRPC integration uses Protocol Buffers and HTTP/2 for high-performance, strongly-typed communication. ### When to Use ✅ **Best for:** - Microservices (service-to-service) - Internal APIs - High-performance requirements - Low-latency communication - Strongly-typed contracts - .NET-to-.NET or polyglot services ### Pros - ✅ **High performance** - Binary protocol, HTTP/2 multiplexing - ✅ **Compact payloads** - Protocol Buffers are smaller than JSON - ✅ **Strong typing** - Compile-time type safety - ✅ **Code generation** - Automatic client generation - ✅ **Streaming** - Bidirectional streaming support - ✅ **Rich error model** - Structured error details ### Cons - ❌ **Browser support limited** - Requires gRPC-Web proxy - ❌ **Learning curve** - .proto files, Protocol Buffers - ❌ **Less human-readable** - Binary format - ❌ **Tooling** - Fewer debugging tools than REST - ❌ **Firewall issues** - HTTP/2 may be blocked ### Example Setup ```csharp var builder = WebApplication.CreateBuilder(args); // Register CQRS builder.Services.AddSvrntyCQRS(); builder.Services.AddDefaultCommandDiscovery(); builder.Services.AddDefaultQueryDiscovery(); // Register handlers builder.Services.AddCommand(); builder.Services.AddQuery(); // Add gRPC builder.Services.AddGrpc(); var app = builder.Build(); // Map gRPC services (auto-generated by source generators) app.MapGrpcService(); app.MapGrpcService(); // Enable gRPC reflection (for tools like grpcurl) app.MapGrpcReflectionService(); app.Run(); ``` ### Proto File Create `Protos/cqrs_services.proto`: ```protobuf syntax = "proto3"; option csharp_namespace = "MyApp.Grpc"; service CommandService { rpc CreateUser (CreateUserRequest) returns (CreateUserResponse); } service QueryService { rpc GetUser (GetUserRequest) returns (GetUserResponse); } message CreateUserRequest { string name = 1; string email = 2; } message CreateUserResponse { int32 result = 1; } message GetUserRequest { int32 user_id = 1; } message GetUserResponse { int32 id = 1; string name = 2; string email = 3; } ``` **Note:** Svrnty.CQRS source generators automatically implement these services for you! ### Usage ```bash # Using grpcurl grpcurl -plaintext \ -d '{"name":"Alice","email":"alice@example.com"}' \ localhost:5000 \ CommandService/CreateUser grpcurl -plaintext \ -d '{"userId":1}' \ localhost:5000 \ QueryService/GetUser ``` ## Dual Protocol (Both HTTP & gRPC) ### What It Is Run both HTTP and gRPC endpoints simultaneously, allowing clients to choose their preferred protocol. ### When to Use ✅ **Best for:** - Hybrid scenarios (public + internal APIs) - Gradual migration from REST to gRPC - Supporting multiple client types - Maximum flexibility ### Example Setup ```csharp var builder = WebApplication.CreateBuilder(args); // Register CQRS builder.Services.AddSvrntyCQRS(); builder.Services.AddDefaultCommandDiscovery(); builder.Services.AddDefaultQueryDiscovery(); // Register handlers builder.Services.AddCommand(); builder.Services.AddQuery(); // Add HTTP support builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Add gRPC support builder.Services.AddGrpc(); var app = builder.Build(); // Map HTTP endpoints app.UseSvrntyCqrs(); // Map gRPC services app.MapGrpcService(); app.MapGrpcService(); app.MapGrpcReflectionService(); // Enable Swagger app.UseSwagger(); app.UseSwaggerUI(); app.Run(); ``` ### Benefits - ✅ **Flexibility** - Clients choose protocol - ✅ **Same codebase** - One implementation, two protocols - ✅ **Gradual migration** - Transition clients over time - ✅ **Best of both** - Public REST + internal gRPC ### Trade-offs - ❌ **Slightly more complexity** - More configuration - ❌ **Two sets of clients** - Maintain both if not auto-generated - ❌ **Larger dependencies** - Both HTTP and gRPC packages ## Performance Comparison ### Latency **gRPC:** ~50% lower latency than HTTP/JSON ``` gRPC: 1-2 ms HTTP/JSON: 2-4 ms ``` *Results vary based on payload size and network conditions* ### Throughput **gRPC:** ~2-3x higher throughput ``` gRPC: 50,000+ requests/sec HTTP/JSON: 15,000-20,000 requests/sec ``` *On same hardware* ### Payload Size **gRPC:** ~30-50% smaller payloads ``` Protocol Buffers: 100 bytes JSON: 200-300 bytes ``` *For typical messages* ## Feature Comparison | Feature | HTTP (Minimal API) | gRPC | |---------|-------------------|------| | **Performance** | Good | Excellent | | **Browser support** | ✅ Yes | ❌ No (requires gRPC-Web) | | **Caching** | ✅ Native HTTP caching | ❌ Not built-in | | **Streaming** | ❌ No (without WebSockets) | ✅ Yes (bidirectional) | | **Code generation** | ❌ No | ✅ Yes | | **Human-readable** | ✅ JSON | ❌ Binary | | **Tooling** | ✅ Excellent (Swagger, Postman) | ⚠️ Limited (grpcurl, Postman) | | **Learning curve** | ✅ Low | ⚠️ Medium | | **Type safety** | ⚠️ Runtime | ✅ Compile-time | ## Decision Matrix ### Choose HTTP If: - ✅ You need browser/JavaScript clients - ✅ Public API for third parties - ✅ You want Swagger documentation - ✅ Team is familiar with REST - ✅ Caching is important - ✅ Human readability matters ### Choose gRPC If: - ✅ Microservices architecture - ✅ Internal APIs only - ✅ Performance is critical - ✅ You need streaming - ✅ Strong typing is important - ✅ Polyglot environment (.NET, Go, Java, Python) ### Choose Both If: - ✅ You have both public and internal clients - ✅ You want flexibility - ✅ You're migrating from REST to gRPC - ✅ Different teams have different needs ## Migration Path ### Start with HTTP 1. Build with HTTP (easy to test, debug) 2. Add gRPC later if needed 3. Same handlers work for both ### Start with gRPC 1. Build with gRPC (for performance) 2. Add HTTP later for public API 3. Same handlers work for both ## Real-World Examples ### E-Commerce Platform ```csharp // Public-facing API → HTTP // Mobile app → HTTP // Internal order processing → gRPC // Payment service → gRPC // Inventory service → gRPC ``` **Recommendation:** Dual protocol ### Internal Microservices ```csharp // All service-to-service → gRPC // Admin dashboard → HTTP (optional) ``` **Recommendation:** gRPC only ### SaaS Product ```csharp // Customer API → HTTP // JavaScript SDK → HTTP // Webhooks → HTTP ``` **Recommendation:** HTTP only ## Next Steps Congratulations! You've completed the Getting Started guide. You now know: - ✅ What CQRS is and when to use it - ✅ How to install Svrnty.CQRS - ✅ How to create commands and queries - ✅ How to add validation - ✅ When to use HTTP vs gRPC ### Continue Learning - **[Architecture](../architecture/README.md)** - Understand the framework design - **[Core Features](../core-features/README.md)** - Deep dive into commands, queries, and dynamic queries - **[HTTP Integration](../http-integration/README.md)** - Master HTTP endpoints - **[gRPC Integration](../grpc-integration/README.md)** - Master gRPC services - **[Event Streaming](../event-streaming/README.md)** - Build event-sourced applications - **[Tutorials](../tutorials/README.md)** - Learn through comprehensive examples ### Try the Sample Project Check out the complete sample application: ```bash cd Svrnty.Sample dotnet run ``` Visit: - HTTP: `http://localhost:5000/swagger` - gRPC: Use grpcurl or a gRPC client ## See Also - [HTTP Integration Overview](../http-integration/README.md) - Complete HTTP guide - [gRPC Integration Overview](../grpc-integration/README.md) - Complete gRPC guide - [Endpoint Mapping](../http-integration/endpoint-mapping.md) - How HTTP endpoints work - [Proto File Setup](../grpc-integration/proto-file-setup.md) - How .proto files work