Definition
- REST – resource-oriented URLs with HTTP methods, JSON payloads, HTTP status codes; simple, cacheable, and browser-friendly.
- gRPC – service methods in a
.protocontract, binary Protocol Buffers, HTTP/2 multiplexing, code-generated typed stubs, four streaming patterns. - GraphQL – a single
/graphqlendpoint with a typed schema; the client queries for exactly the fields it needs, curing over-fetching and under-fetching. - Trade-off axis – REST maximizes simplicity and ubiquity, gRPC maximizes performance and contract safety, GraphQL maximizes client flexibility.
At National Bank of India, REST is the plain printed form in everyday language that any partner can fill in without training. gRPC is the fast internal shorthand on a dedicated phone line between departments. GraphQL is a smart request slip where you write exactly the fields you want and get back precisely that. Each style fits a different relationship.
Understanding the Concepts
What is REST?
REST organizes the API around resources addressed by URLs, with HTTP methods expressing actions and HTTP status codes expressing outcomes. The payload is usually JSON, which is human-readable.
GET /api/v1/accounts/SAV2001 → fixed JSON shape, cacheable
{
"accountId": "SAV2001",
"holderName": "Rajesh",
"balance": 150000.00
}
REST runs over HTTP/1.1 or HTTP/2, works in every browser and language, and benefits from URL-based HTTP caching and CDNs. Its weaknesses are over-fetching (endpoint returns more fields than needed) and under-fetching (multiple calls for one view).
What is gRPC?
gRPC organizes the API around service methods defined in a .proto contract. The payload is binary Protocol Buffers, smaller and faster than JSON. It runs on HTTP/2 with multiplexing and streaming.
service TransferService {
rpc Transfer (TransferRequest) returns (TransferReply);
}
message TransferRequest { string from = 1; string to = 2; int64 amount_paise = 3; }
message TransferReply { string transfer_id = 1; string status = 2; }
// Generated stub – remote call looks like a local method:
TransferReply reply = stub.transfer(
TransferRequest.newBuilder()
.setFrom("SAV2001").setTo("CUR3001")
.setAmountPaise(5000000).build());
What is GraphQL?
GraphQL exposes a single endpoint with a typed schema. The client sends a query naming exactly the fields it wants.
query {
account(number: "SAV2001") {
balance
transactions(last: 3) { amount type }
}
}
One request, exact fields, no over-fetching or under-fetching.
How do REST, gRPC, and GraphQL compare? (comparison table)
| Aspect | REST | gRPC | GraphQL |
|---|---|---|---|
| Format | JSON (text) | Protobuf (binary) | JSON query/response |
| Transport | HTTP/1.1 or 2 | HTTP/2 | HTTP (POST to one URL) |
| Contract | OpenAPI spec | .proto file | GraphQL schema |
| Human-readable | Yes | No | Query yes, tools needed |
| Browser support | Native | Needs gRPC-Web proxy | Needs client library |
| HTTP caching | URL-based, natural | Not available | Harder (single POST URL) |
| Streaming | SSE/WebSocket workaround | First-class (4 patterns) | Subscriptions (WebSocket) |
| Code generation | Optional | Required (typed stubs) | Optional |
| Best for | Public APIs, simplicity | Internal high-throughput | Diverse client views |
When should you use REST?
Use REST for public-facing APIs where simplicity and ubiquity matter, when HTTP caching is valuable, and when partners need to integrate quickly with standard tooling.
# Anyone can call a REST API:
curl -X GET https://api.bank.com/api/v1/accounts/SAV2001 \
-H "Authorization: Bearer token123"
When should you use gRPC?
Use gRPC for internal microservice-to-microservice calls where latency and throughput matter, where strict typed contracts are needed across polyglot services, and where streaming is useful.
// Internal mesh – fast binary:
Transfer Service ═══gRPC═══ Fraud Service
═══gRPC═══ Account Service
When should you use GraphQL?
Use GraphQL when many clients (mobile, web, partners) need different subsets of a connected data graph, and over-fetching and under-fetching genuinely hurt.
// Mobile asks for 3 fields, web asks for 10 – same graph:
query { account(number: "SAV2001") { balance } } // mobile
query { account(number: "SAV2001") { balance, holderName, branchCode, ... } } // web
How do teams combine all three?
A common architecture: gRPC for the internal mesh, REST at the public edge, GraphQL as an aggregation layer for complex views. A gateway translates between them.
External:
┌──────────┐ REST/JSON ┌──────────┐ gRPC ┌──────────────┐
│ Partners │ ────────────→│ Gateway │ ═════════→│ Transfer Svc │
└──────────┘ └──────────┘ └──────────────┘
Mobile/Web:
┌──────────┐ GraphQL ┌──────────┐ gRPC ┌──────────────┐
│ Client │ ────────────→│ GraphQL │ ═════════→│ Account Svc │
└──────────┘ │ Gateway │ ═════════→│ Card Svc │
└──────────┘ └──────────────┘
What are common mistakes?
The most common mistake is choosing based on fashion rather than client type and traffic. Using gRPC for a public partner API raises the integration barrier. Using GraphQL for simple CRUD adds complexity. Using REST for high-volume internal mesh wastes performance.
What should a senior engineer know?
The decision is about client type, performance needs, and governance. REST at the public edge for simplicity and caching. gRPC inside for speed and typed contracts. GraphQL for aggregation when clients need diverse shapes. All three sit as thin adapters over the same business service, showing the style is a transport choice, not a different implementation of the logic. In regulated banking, REST's status codes and HTTP caching are well understood by every intermediary, gRPC's typed contracts enforce exact message shapes between critical services, and GraphQL's query-cost limits are mandatory to prevent denial-of-service.
Visual Overview
REST vs gRPC vs GraphQL:
REST: GET /accounts/SAV2001 → { fixed JSON, 20 fields }
Simple, cacheable, browser-friendly
gRPC: stub.getBalance(SAV2001) → binary, 25 bytes
Fast, typed, HTTP/2 streaming
GraphQL: POST /graphql { account { balance } } → { exact fields }
Flexible, one trip, client decides shape
┌─────────────────────────────────────────────────┐
│ Mature Architecture: │
│ Public edge → REST (simplicity, caching) │
│ Internal mesh → gRPC (speed, typed contracts) │
│ Client views → GraphQL (flexible shapes) │
└─────────────────────────────────────────────────┘
Key Takeaway
REST, gRPC, and GraphQL are three API styles with different trade-offs. REST uses human-readable JSON over HTTP with resource URLs and status codes, maximizing simplicity, caching, and ubiquity. gRPC uses binary Protocol Buffers over HTTP/2 with code-generated typed stubs, maximizing performance and contract safety. GraphQL exposes a single typed endpoint where the client specifies exactly which fields it needs, maximizing flexibility.
The transport and format drive the trade-offs. REST is universal and debuggable but relatively heavy. gRPC is fast and efficient but opaque. GraphQL is flexible but harder to cache and govern. There is no universally best choice.
At National Bank of India, all three coexist. Fintech partners integrate fastest with plain JSON, so the public API is REST. Internally, the transfer service calls fraud and account services at high volume, so the mesh is gRPC for speed and typed contracts. The mobile and web dashboards need different field subsets, so a GraphQL aggregation layer lets each ask for exactly its shape, with depth and complexity limits.
The decision is about client type, performance, and governance. REST at the public edge, gRPC inside, GraphQL for aggregation, each earning its place where it fits best.
Remember one sentence: REST for the outside world, gRPC for the inside highway, GraphQL for the smart client layer, and each style wraps the same business logic.
---