Once an app is split into many small services (order, payment, delivery, search), they have to talk. There are several ways — REST, gRPC, GraphQL, WebSockets, messaging — and picking the right one per conversation is a real skill. This post makes it simple, using Swiggy.
First, the master switch: Sync vs Async
Everything below is a flavor of one of these two.
| Synchronous | Asynchronous | |
|---|---|---|
| Meaning | Call → wait for the reply | Fire a message → move on |
| Analogy | A phone call | A WhatsApp text |
| Both must be online? | Yes | No — receiver can be busy/down |
| Swiggy example | "Is this coupon valid?" (need answer now) | "Order placed" (tell others, don't wait) |
Hold this in your head — it explains every choice that follows.
1. REST — the default
Standard web API over HTTP. You request, it responds. JSON in, JSON out.
App → GET /restaurants/123 → Order Service → JSON back
| ✅ Good | ❌ Bad |
|---|---|
| Universal, everyone knows it | Chatty — many calls for related data |
| Easy to debug (just URLs) | Sends fixed fields (too much or too little) |
| Cacheable | Heavier than binary formats |
Swiggy: your app asking "get this restaurant's menu." Classic REST.
2. gRPC — fast, internal
Binary and quick. Used between services, not for browsers.
Order service → gRPC → Delivery service (internal, fast, typed)
| ✅ Good | ❌ Bad |
|---|---|
| Very fast, tiny payloads | Not browser-friendly |
| Strict, typed contract | Harder to read/debug |
| Streaming built in | Overkill for simple things |
Rule of thumb: REST for the outside (public/app), gRPC for the inside (service ↔ service, millions of fast calls).
3. GraphQL — ask for exactly what you want
One endpoint. The client lists the exact fields it needs — nothing more.
REST: 3 calls → /restaurant + /menu + /reviews
GraphQL: 1 call → "give me name, menu items, top 3 reviews"
| ✅ Good | ❌ Bad |
|---|---|
| No wasted data | More complex to set up |
| One call for nested data | Caching is harder |
| Great for mobile (saves bandwidth) | Can hide expensive queries |
Swiggy: the restaurant screen needs name + menu + ratings + offers. REST would be 4 calls; GraphQL does it in 1 tailored call.
4. WebSockets / SSE — the server pushes to you
A connection that stays open, so the server can send you updates without you asking.
| WebSocket | SSE | |
|---|---|---|
| Direction | Two-way | One-way (server → you) |
| Use | Chat, live map | Live feed, notifications |
Bike moves → server PUSHES → 🛵 dot updates (no refresh!)
Swiggy: the live tracking map. The server pushes the bike's new position to you — you don't keep hitting refresh.
5. Async messaging — fire and forget
Drop a message on a queue. Don't wait. The receiver handles it whenever it can.
Order placed → [message] → queue → payment & restaurant pick it up later
| ✅ Good | ❌ Bad |
|---|---|
| Fully decoupled (receiver can be offline) | No instant reply |
| Absorbs traffic spikes | Harder to trace end-to-end |
| Reliable delivery + retries | Eventual, not immediate |
Swiggy: "order placed" is dropped on a queue; payment, restaurant, and analytics each react in their own time.
How to actually choose
Need an answer right now?
├─ Yes → SYNC
│ ├─ Public / app-facing? → REST
│ ├─ Internal service ↔ service? → gRPC
│ └─ Client picks the fields? → GraphQL
│
└─ No, fire and forget → ASYNC
├─ Server pushes live updates? → WebSocket / SSE
└─ Reliable background handoff? → messaging queue
The senior insight
You don't pick one. A single Swiggy order uses several at once:
- REST from your app in
- gRPC between internal services
- Messaging for side-effects (notify restaurant, analytics)
- WebSocket for the live map back to you
You don't choose a communication style for the whole system. You choose it per hop — the right tool for each conversation.
Top comments (0)