REST vs RPC
REST organizes APIs around resources (nouns) with standard HTTP methods. RPC organizes APIs around actions (verbs) with custom method names.
REST vs RPC (gRPC)
REST organizes APIs around resources (nouns) with standard HTTP methods. RPC organizes APIs around actions (verbs) with custom method names. REST is more standardized; RPC is more flexible for complex operations.
The Case for REST
Resource-oriented. GET /users/123, POST /orders. Standard HTTP methods.
What you gain: Standardized and well-understood. Naturally cacheable. Self-documenting URLs. Browser-friendly.
What you lose: Verbose for complex operations. Over-fetching or under-fetching data. Not ideal for streaming or real-time.
Best when: Public APIs; CRUD-heavy applications; Web frontends; When cacheability matters.
The Case for RPC (gRPC)
Action-oriented. CreateUser(), PlaceOrder(). Binary protocol (protobuf).
What you gain: Strongly typed with code generation. High performance (binary, HTTP/2). Supports streaming. Better for internal services.
What you lose: Not browser-friendly (needs proxy). Not cacheable by default. Tighter coupling between client and server.
Best when: Internal microservice communication; High-performance requirements; Streaming data (bidirectional); Polyglot systems (code generation).
Side-by-Side
| REST | RPC (gRPC) | |
|---|---|---|
| Strengths | Standardized and well-understood | Strongly typed with code generation |
| Weakness | Verbose for complex operations | Not browser-friendly (needs proxy) |
| Use when | Public APIs | Internal microservice communication |
In the Real World
Google uses gRPC for internal microservice communication (millions of RPCs per second).
Stripe uses REST for their public API (developer-friendly, cacheable, well-documented).
Netflix uses gRPC between internal services and REST for their public API.
The Interview Take
Use REST for external/public APIs and gRPC for internal service-to-service communication. Mention this hybrid approach in interviews.
Source | System-Design-Overview
Practical Implementation for .NET Developers
In a .NET application, you would typically implement this pattern using the following approach:
ASP.NET Core setup: Create a service class that encapsulates the logic, register it with dependency injection, and inject it into your controllers or minimal API endpoints. The built-in DI container handles lifecycle management.
Entity Framework Core: For database interactions, EF Core provides the ORM layer. Use migrations for schema management and raw SQL for performance-critical queries. Consider Dapper for read-heavy paths where EF Core's overhead matters.
Azure integration: If deploying to Azure, leverage managed services — Azure Cache for Redis, Azure SQL, Azure Service Bus, Azure Cosmos DB. These eliminate operational overhead and provide built-in monitoring through Application Insights.
Testing: Use xUnit with Testcontainers for integration tests that spin up real databases in Docker. Mock external dependencies with NSubstitute. The WebApplicationFactory class lets you test your entire HTTP pipeline in-process.
Monitoring: Add Application Insights telemetry to track request latency, dependency calls, and custom metrics. Use structured logging with Serilog to make production debugging possible:
Log.Information("Processing order {OrderId} for {CustomerId}", orderId, customerId);
This gives you searchable, structured logs in Azure Monitor or Seq.
Real-World Decision Framework
REST (Representational State Transfer) treats everything as a resource accessed via standard HTTP methods. RPC (Remote Procedure Call) treats remote services as functions you call with parameters. Both are valid patterns with different strengths.
When REST Wins
REST is the default choice for public-facing APIs and web applications:
- Public APIs: Stripe, GitHub, and Twilio all use REST. It is the most widely understood API style.
- CRUD applications: When your operations map naturally to Create, Read, Update, Delete, REST is intuitive. GET /users/123, POST /orders, DELETE /items/456.
- Browser clients: REST works over standard HTTP, which every browser and mobile framework supports natively.
- Caching: REST responses are cacheable because GET requests are idempotent. CDNs and browser caches work out of the box.
Technologies: HTTP/JSON, OpenAPI/Swagger, Express.js, ASP.NET Web API, Django REST Framework.
When RPC Wins
RPC excels for internal service-to-service communication where performance matters:
- Microservice communication: gRPC with Protocol Buffers provides type-safe, high-performance calls between internal services. Google uses gRPC for virtually all internal service communication.
- Streaming: gRPC supports bidirectional streaming — useful for real-time data feeds, chat, and IoT.
- Performance-critical paths: gRPC with Protobuf serialization is 5-10x faster than REST with JSON for serialization/deserialization.
- Polyglot environments: gRPC generates client and server code in 10+ languages from a single .proto definition.
Technologies: gRPC, Thrift, tRPC, Protocol Buffers, Avro.
The Modern Pattern: REST Outside, gRPC Inside
Most large-scale systems use REST for external APIs (consumed by web/mobile clients) and gRPC for internal service-to-service calls. This gives you broad client compatibility externally and high performance internally.
Interview Decision Guide
- Who consumes this API? External developers → REST. Internal services → consider gRPC.
- What is the data format? Flexible/self-documenting → REST/JSON. Compact/typed → gRPC/Protobuf.
- Do you need streaming? Yes → gRPC. No → REST is fine.
- Do you need browser support? Yes → REST (gRPC-Web exists but adds complexity). No → either works.
.NET Implementation
REST: Use ASP.NET Core Minimal APIs or Controllers with [ApiController]. gRPC: Use Grpc.AspNetCore package — define services in .proto files, generate C# code with Grpc.Tools. Both can coexist in the same ASP.NET Core application on different ports.