Skip to content

The API Landscape

TL;DR

There are three main API styles — REST (resource-oriented, the default choice), GraphQL (client picks exactly what data it wants), and RPC (call remote functions like local ones). Each solves different problems. Default to REST unless you have a specific reason not to.

What Is an API, Really?

Imagine two people who speak different languages trying to order food at a restaurant. They need a menu — a shared agreement on what's available, how to ask for it, and what to expect back. An API (Application Programming Interface) is that menu for software.

When your frontend needs user data, it doesn't reach into the database directly. It asks the backend through an API: "Give me user 42's profile." The API defines how to ask, what you can ask for, and what the response looks like.

In system design, API design is one of the first things you'll sketch out. It determines how every component in your system talks to every other component. Get it wrong, and you'll feel the pain in every service, every client, and every future feature.

Why does this matter for interviews? Interviewers want to see that you can define clear contracts between systems. The protocol you choose — REST, GraphQL, or RPC — signals that you understand the trade-offs and can pick the right tool for the job.

API protocols comparison

The Three Main Protocols

Think of these three protocols as three different ways to organize a library.

  • REST is like a traditional library. Every book has a shelf location (URL). You go to the shelf, pick up the book, and get the whole thing. Want a different book? Go to a different shelf.
  • GraphQL is like a librarian who takes custom requests. You say "I want the title and author of book #42, plus the first 3 reviews." The librarian assembles exactly what you asked for — nothing more, nothing less.
  • RPC is like calling a friend who works at the library. You say "Hey, can you look up who wrote that book about algorithms?" They run a function on their end and give you the answer. You don't care how the library is organized — you just called a function.

Here's how each one works.


REST — The Default Choice

REST (Representational State Transfer) is the most widely used API style on the web. It's resource-oriented — everything is a "resource" with a URL, and you interact with resources using standard HTTP methods.

The Mental Model

Think of REST like a filing cabinet. Each drawer is a resource (users, orders, products). You interact with the filing cabinet using a small set of actions:

HTTP Method Action Example What It Does
GET Read GET /users/42 Fetch user 42's profile
POST Create POST /users Create a new user
PUT Replace PUT /users/42 Replace user 42's entire profile
PATCH Update PATCH /users/42 Update specific fields on user 42
DELETE Delete DELETE /users/42 Delete user 42

This maps directly to CRUD (Create, Read, Update, Delete) — the four basic operations on any data.

What a REST API Looks Like

GET /api/users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGci...

---

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 42,
  "name": "Alice",
  "email": "alice@example.com",
  "created_at": "2025-01-15T09:30:00Z"
}

Clean, predictable, and human-readable. You can test REST APIs with curl, a browser, or any HTTP client. That simplicity is a huge advantage.

Why REST Is the Default

  • Everyone knows it. Every developer, every framework, every tool supports REST.
  • HTTP semantics are built-in. Status codes (200, 404, 500), caching headers, content negotiation — you get these for free.
  • Stateless. Each request contains everything the server needs. No session state to manage. This makes scaling straightforward — any server can handle any request.
  • Tooling is incredible. Swagger/OpenAPI for docs, Postman for testing, CDNs for caching — the ecosystem is massive.

REST's Weaknesses

  • Over-fetching. GET /users/42 returns everything about the user, even if you only need their name. On mobile networks, this wastes bandwidth.
  • Under-fetching. To build a user profile page, you might need GET /users/42, then GET /users/42/posts, then GET /users/42/followers — three round trips for one screen.
  • Rigid endpoints. Every new data need often means a new endpoint or a new query parameter.

Interview Tip

When an interviewer asks you to design an API, start with REST. It's the safe, correct default. Only switch to something else if you can articulate why REST doesn't work for your specific scenario.

Who Uses REST?

Stripe built one of the most respected REST APIs in the industry. Twilio, GitHub (their primary API), Twitter/X, and most SaaS products expose REST APIs. It's the lingua franca of the web.


GraphQL — The Client Is in Control

GraphQL was created by Facebook in 2012 and open-sourced in 2015. It was born out of a specific problem: their mobile app needed very different data than their web app, and managing dozens of REST endpoints for each use case was becoming a nightmare.

The Mental Model

With REST, the server decides what data you get back. With GraphQL, the client decides. There's a single endpoint (POST /graphql), and the client sends a query describing exactly what it wants.

What a GraphQL Query Looks Like

# Client sends this query
query {
  user(id: 42) {
    name
    email
    posts(first: 3) {
      title
      createdAt
    }
    followers {
      count
    }
  }
}
// Server responds with exactly this shape
{
  "data": {
    "user": {
      "name": "Alice",
      "email": "alice@example.com",
      "posts": [
        { "title": "Learning GraphQL", "createdAt": "2025-03-01" },
        { "title": "API Design Tips", "createdAt": "2025-02-15" },
        { "title": "My First Post", "createdAt": "2025-01-10" }
      ],
      "followers": {
        "count": 1284
      }
    }
  }
}

One request. Exactly the data you need. No over-fetching, no under-fetching, no multiple round trips.

Why GraphQL Shines

  • No over-fetching. The client asks for name and email — that's all it gets. No wasted bandwidth.
  • No under-fetching. One query can traverse relationships (user → posts → comments) in a single request. No waterfall of REST calls.
  • Diverse clients. A mobile app can request minimal data. A web dashboard can request everything. Same backend, same endpoint.
  • Self-documenting. The schema is the documentation. Tools like GraphiQL let developers explore the API interactively.
  • Strong typing. Every field has a type. The schema enforces it. Clients know exactly what to expect.

GraphQL's Weaknesses

  • Complexity on the server. You need to build resolvers, handle nested queries, and prevent expensive operations. REST gives you a lot of this for free via HTTP.
  • Caching is harder. REST endpoints map cleanly to URLs, so HTTP caching and CDNs work out of the box. GraphQL uses POST for everything, so you need application-level caching (Apollo Client, Relay, etc.).
  • N+1 query problem. A naive resolver for "all users and their posts" will fire one database query per user. You need tools like DataLoader to batch these.
  • Security surface area. A malicious client could send a deeply nested query that hammers your database. You need query depth limiting, cost analysis, and rate limiting.
  • Learning curve. Your team needs to learn the query language, schema definition, resolvers, and client libraries.

Interview Tip

Don't reach for GraphQL just because it sounds modern. If the interviewer's system has one type of client (say, a web dashboard) with straightforward data needs, REST is simpler and better. GraphQL earns its keep when you have multiple clients with different data needs.

Who Uses GraphQL?

GitHub launched their GraphQL API (v4) alongside their REST API because integrators needed wildly different subsets of data. Shopify, Airbnb, Meta/Facebook, and Netflix (for their studio tools) all use GraphQL where it makes sense.


RPC — Calling Functions Over the Network

RPC (Remote Procedure Call) is the oldest pattern of the three, and arguably the most intuitive. The idea is simple: you call a function on a remote server as if it were a local function.

The Mental Model

REST thinks in resources (nouns): /users, /orders, /products. RPC thinks in actions (verbs): createUser(), calculateShipping(), sendEmail().

Instead of "what resource am I operating on?", you ask "what function do I want to call?"

What RPC Looks Like

There are many RPC implementations, but the two you'll encounter most are:

JSON-RPC (simple, HTTP-based):

// Request
{
  "method": "getUserProfile",
  "params": { "userId": 42 },
  "id": 1
}

// Response
{
  "result": {
    "name": "Alice",
    "email": "alice@example.com"
  },
  "id": 1
}

gRPC (Google's modern RPC framework) uses Protocol Buffers for binary serialization:

// user_service.proto — the contract
service UserService {
  rpc GetUser (GetUserRequest) returns (UserResponse);
  rpc CreateUser (CreateUserRequest) returns (UserResponse);
}

message GetUserRequest {
  int32 user_id = 1;
}

message UserResponse {
  int32 id = 1;
  string name = 2;
  string email = 3;
}

The .proto file generates client and server code in any language. Your Go service and your Python service can talk to each other with type-safe, auto-generated code. No hand-writing HTTP requests. No parsing JSON.

  • Binary serialization with Protocol Buffers. This is the big one. Instead of sending human-readable JSON text ({"name": "Alice"}), Protocol Buffers encode data into a compact binary format. Smaller payloads, faster serialization/deserialization.
  • HTTP/2 under the hood. gRPC uses HTTP/2, which gives you multiplexing (multiple requests over one connection), header compression, and bidirectional streaming.
  • Code generation. Define your API once in a .proto file, generate client and server code in Go, Java, Python, C++, etc. No mismatched types between services.
  • Streaming. gRPC natively supports server streaming, client streaming, and bidirectional streaming — essential for things like real-time data feeds.
  • Strong contracts. The .proto file is the single source of truth. Both sides know exactly what to send and expect.

A Critical Misconception: "gRPC Is Faster Than HTTP"

You'll hear this in interviews and online debates — and it's wrong.

gRPC is not "faster than HTTP." gRPC uses HTTP/2. It literally runs on top of HTTP. The performance advantage comes from two things:

  1. Binary serialization (Protocol Buffers) is much more compact and faster to parse than JSON text. A message that's 100 bytes in JSON might be 30 bytes in Protocol Buffers.
  2. HTTP/2 features like multiplexing and header compression reduce overhead compared to HTTP/1.1.

If you used HTTP/2 with a binary format like BSON (Binary JSON, used by MongoDB) or MessagePack instead of plain JSON, you'd get similar performance benefits. The speed isn't magic — it's the binary encoding.

Interview Tip

If you mention gRPC in an interview, be ready to explain why it's fast. Saying "gRPC is faster than REST" is a yellow flag. Saying "gRPC uses Protocol Buffers for binary serialization over HTTP/2, which reduces payload size and parsing time compared to JSON over HTTP/1.1" is a green flag.

RPC's Weaknesses

  • Not browser-friendly. Browsers speak HTTP natively. gRPC requires a proxy layer (gRPC-Web or an Envoy sidecar) to work in browsers. This is why gRPC is almost always used for backend-to-backend communication.
  • Tighter coupling. Both client and server need the .proto file. Changing the API means regenerating code on both sides.
  • Less discoverable. You can't just curl a gRPC endpoint and see what happens. REST APIs are inherently explorable.
  • Overkill for simple APIs. If you have a CRUD API with 5 endpoints, REST is simpler and more appropriate.

Who Uses RPC/gRPC?

Google created gRPC and uses it extensively for internal service communication. Netflix, Square, Uber, and Dropbox use gRPC for performance-critical microservice communication. Slack uses it for their real-time messaging backend. Buf and the Connect protocol are making gRPC more accessible for web-facing APIs.


Real-Time Protocols — A Brief Mention

Not everything fits the request-response model. Some features need data pushed to the client in real time.

Protocol Direction Use Case How It Works
WebSockets Bidirectional Chat, gaming, collaborative editing Persistent TCP connection, both sides send messages freely
Server-Sent Events (SSE) Server → Client only Live feeds, notifications, dashboards HTTP connection stays open, server pushes events
WebRTC Peer-to-peer Video calls, screen sharing Direct browser-to-browser connection, bypasses your server

These aren't replacements for REST, GraphQL, or RPC — they complement them. A typical system might use REST for CRUD operations and WebSockets for real-time updates.

We covered these in depth in the Networking course, Chapter 4: Real-Time Communication. If you haven't read that yet, it's worth the detour.

Interview Tip

If the system you're designing has a real-time component (chat, live updates, notifications), briefly mention which real-time protocol you'd use and why. Don't deep-dive unless the interviewer asks — just show you're aware of the options.


The Big Comparison Table

REST GraphQL gRPC
Mental model Resources (nouns) Queries (ask for what you want) Functions (verbs)
Data format JSON (text) JSON (text) Protocol Buffers (binary)
Transport HTTP/1.1 or HTTP/2 HTTP (typically POST) HTTP/2
Endpoint structure Multiple endpoints (/users, /posts) Single endpoint (/graphql) Service methods (GetUser(), CreateOrder())
Who controls the response shape? Server Client Server (defined in .proto)
Caching Excellent (HTTP caching, CDNs) Harder (needs client-side caching) Limited (no HTTP caching semantics)
Browser support Native Native (just HTTP) Requires proxy (gRPC-Web)
Streaming Limited (SSE, chunked) Subscriptions (add-on) Native (bidirectional)
Best for Public APIs, CRUD, web apps Multi-client apps, mobile, complex data needs Microservices, internal APIs, high-performance
Learning curve Low Medium-High Medium
Tooling maturity Excellent Good and growing Good for backend; limited for frontend

Real-World Patterns: Who Uses What

Company Public API Internal Communication Why
Stripe REST Mix of REST + internal RPC REST is perfect for a payment API — predictable, well-documented, cacheable
GitHub REST (v3) + GraphQL (v4) Internal services Added GraphQL because integrators needed flexible data access
Google REST (public Cloud APIs) gRPC (internal) gRPC was born here — billions of internal RPC calls per second
Netflix GraphQL (for studio tools) gRPC between services Different tools for different problems
Shopify GraphQL (primary) Mix Their merchants/partners need flexible queries for diverse storefronts

Notice the pattern: REST for public, gRPC for internal, GraphQL when clients need flexibility. This isn't a coincidence — it's a natural result of each protocol's strengths.


Quick Recap

  • APIs are contracts between systems. The protocol you choose determines how those contracts look and feel.
  • REST is the default. Resource-oriented, HTTP-native, simple, and well-tooled. Start here.
  • GraphQL gives clients control over what data they receive. Best when you have multiple clients with different needs.
  • RPC (especially gRPC) is for internal, performance-critical communication. Binary serialization + HTTP/2 = fast. But it's not browser-friendly.
  • gRPC's speed comes from Protocol Buffers' binary encoding, not from avoiding HTTP. It literally uses HTTP/2.
  • Real-time protocols (WebSockets, SSE, WebRTC) complement request-response APIs — they don't replace them.
  • Most real-world systems mix protocols. REST for public APIs, gRPC for microservices, WebSockets for real-time features. That's not over-engineering — it's using the right tool for each job.

Interview Expectations: Junior vs. Senior

  • Junior/Mid-level: Expected to know the basic differences between REST, GraphQL, and RPC. Can explain that REST is resource-based and GraphQL prevents over-fetching.
  • Senior/Staff: Expected to articulate the trade-offs of each protocol beyond the surface level. For example, understanding that gRPC is fast because of binary serialization (Protocol Buffers) and HTTP/2 multiplexing, not just because "it's RPC." Knows that REST is the safest default for cacheability, predictability, and standard tooling.