The Protocol Stack
Every network interaction sits on a stack of protocols. Understanding which layer you're operating at helps you make better trade-offs.
TCP vs UDP
Connection-oriented. Guarantees delivery, ordering, and error checking. Slower due to handshake and acknowledgments.
- 3-way handshake to establish connection
- Retransmits lost packets
- Flow control and congestion avoidance
- Use for: HTTP, databases, file transfer, email
Connectionless. Fire-and-forget. No delivery guarantee, no ordering, no handshake. Fast.
- No connection setup overhead
- Lost packets are just lost
- Lower latency, higher throughput
- Use for: Video streaming, gaming, DNS, VoIP
The rule of thumb: Use TCP when data integrity matters (you can't lose or reorder packets). Use UDP when speed matters more than completeness (a dropped video frame is fine, but a lagged stream isn't).
HTTP
HTTP is the application-layer protocol that powers the web. It's request-response based: a client sends a request with a method, URL, headers, and optional body. The server returns a status code, headers, and optional body.
HTTP Methods
| Method | Purpose | Idempotent? | Has body? |
|---|---|---|---|
| GET | Read a resource | Yes | No |
| POST | Create a resource or trigger action | No | Yes |
| PUT | Replace a resource entirely | Yes | Yes |
| PATCH | Partially update a resource | No* | Yes |
| DELETE | Remove a resource | Yes | Optional |
REST
REST (Representational State Transfer) is an architectural style for APIs, not a protocol. A RESTful API models your domain as resources with standard CRUD operations mapped to HTTP methods:
| Operation | HTTP | URL | Example |
|---|---|---|---|
| List | GET | /users | Get all users |
| Read | GET | /users/42 | Get user 42 |
| Create | POST | /users | Create new user |
| Update | PUT | /users/42 | Replace user 42 |
| Delete | DELETE | /users/42 | Delete user 42 |
REST works well when your domain maps naturally to resources and CRUD operations. It's intuitive, cacheable (GET responses are inherently cacheable), and widely tooled.
REST Limitations
- Over-fetching:
GET /users/42returns the entire user object even if you only need the name. - Under-fetching: Getting a user's profile, posts, and followers requires 3 separate API calls.
- Action-oriented operations: "Send a password reset email" doesn't map cleanly to a resource. You end up with awkward endpoints like
POST /password-reset-requests.
RPC
RPC (Remote Procedure Call) treats remote service calls like local function calls. Instead of "GET the user resource at this URL," it's "call the getUser function on the remote server with these arguments."
GET /users/42/orders?status=active Resource-oriented. Standard HTTP semantics.
getActiveOrders(userId: 42) Action-oriented. Explicit function call.
Modern RPC frameworks like gRPC use Protocol Buffers for serialization (much smaller and faster than JSON) and HTTP/2 for transport (multiplexing, streaming, header compression). This makes them significantly more efficient than REST for service-to-service communication.
| Aspect | REST | RPC (gRPC) |
|---|---|---|
| Model | Resources (nouns) | Functions (verbs) |
| Serialization | JSON (text) | Protobuf (binary) |
| Streaming | Limited (SSE, WebSocket) | Native bidirectional |
| Browser support | Native | Requires grpc-web proxy |
| Best for | Public APIs, web clients | Internal microservices |
GraphQL
GraphQL solves the over-fetching and under-fetching problems of REST. The client specifies exactly what data it needs in a single query, and the server returns exactly that — nothing more, nothing less.
Trade-off: GraphQL shifts complexity to the server (resolvers, query optimization, N+1 prevention) and eliminates HTTP-level caching (everything is a POST). It shines for complex, nested data requirements (mobile apps, dashboards) but is overkill for simple CRUD APIs.