Skip to content
Intermediate11 min study

REST, GraphQL, and WebSockets

Match an API style to the actual data-fetching and real-time shape of the problem.

Question progress0 / 10 completed
Start the lesson
REST, GraphQL, and WebSockets visual explanation

WHAT YOU WILL BE ABLE TO DO

Learning outcomes

  • Explain rest, graphql, and websockets in plain language.
  • Connect the behavior to the underlying browser or framework model.
  • Implement the core pattern and reason through edge cases.
  • Answer common follow-ups without relying on memorized phrases.

01Explain it simply

REST models an API as resources addressed by URLs and manipulated with HTTP methods. GraphQL models an API as a typed schema the client queries for exactly the fields it needs in one request. WebSockets open a persistent bidirectional connection for continuous real-time updates instead of the client repeatedly asking.

One-line definition: Match an API style to the actual data-fetching and real-time shape of the problem.

02Mental model

Think about the shape of the problem: REST fits resource-oriented CRUD where HTTP caching and simplicity matter; GraphQL fits UIs that need to compose data from many underlying sources without over- or under-fetching; WebSockets or SSE fit when the server needs to push updates without being asked.

03Step by step

  • Identify whether the client needs a stable resource shape (REST) or a flexible per-screen shape (GraphQL).
  • Check whether HTTP-layer caching is important — REST benefits directly, GraphQL usually needs its own caching layer.
  • Determine whether updates must be pushed continuously, which rules out plain request/response.
  • Choose SSE for one-way server push, WebSockets for bidirectional real-time.
  • Consider that these approaches can coexist in the same system for different concerns.

04Working example

JavaScript
// REST: resource + methodGET /api/orders/42
// GraphQL: client-shaped query, one round tripquery { order(id: 42) { id total items { name price } } }
// WebSocket: persistent channel, server can push anytimeconst socket = new WebSocket('wss://api.example.com/orders/42/updates');socket.onmessage = (event) => updateOrder(JSON.parse(event.data));

The REST call returns whatever shape /orders/42 is defined to return. The GraphQL query lets the client ask for exactly items.name and items.price without a second request. The WebSocket stays open so the server can push an update the moment the order changes, with no polling.

05Where it is used

  • REST for public APIs, resource-oriented CRUD, and CDN-cacheable reads
  • GraphQL for dashboards composing many nested data sources per screen
  • WebSockets for chat, live collaboration, and trading tickers
  • SSE for one-way live feeds like notifications or progress updates

06Common mistakes

  • Adding GraphQL to avoid over-fetching on a simple CRUD API that didn't have that problem
  • Polling REST endpoints every second instead of using a push mechanism for real-time data
  • Assuming GraphQL is automatically cacheable the way GET REST responses are
  • Using a WebSocket when data only flows client-to-server occasionally, where plain requests are simpler

07Interview answer

Justify the choice by over/under-fetching, caching needs, and push-vs-pull — not by declaring one approach universally 'modern' or 'better.'

A dashboard shows five widgets, each needing a different, deeply nested slice of the same underlying data. What problem does REST tend to create here, and how does GraphQL address it?

REST would either need five separate requests or one bloated endpoint returning everything; GraphQL lets each widget's query request exactly the nested fields it needs in a single round trip, without over-fetching or a new endpoint per screen shape.

DDConcept deep dives

Deep dive 1

Fetching shape versus real-time shape are different axes

REST versus GraphQL is mainly a question of how flexibly a client can shape a single request/response. WebSockets versus request/response is an orthogonal question of whether the server needs to push data without being asked. A system can combine either fetching style with either communication style based on each feature's actual needs.

  • Don't treat 'real-time' and 'flexible querying' as the same problem.
  • A GraphQL API can also expose a subscription mechanism for push updates.
  • Choosing one paradigm for the whole system can force a bad fit for a feature with different needs.

Deep dive 2

REST's resource shape trades flexibility for cacheability

A REST GET response tied to a stable URL can be cached by browsers, CDNs, and intermediate proxies using ordinary HTTP caching semantics. GraphQL's flexibility to shape each query differently is exactly what makes URL-based caching not apply directly, requiring a purpose-built caching layer such as a normalized client store or persisted queries.

  • HTTP caching headers apply naturally to REST's stable resource URLs.
  • GraphQL needs deliberate caching infrastructure to get comparable benefits.
  • Persisted queries can restore some CDN-cacheability to GraphQL by using stable query ids.

Deep dive 3

Push mechanisms trade simplicity for real-time capability

Polling is the simplest way to get updated data and works with plain request/response infrastructure, but wastes requests and adds latency bounded by the poll interval. WebSockets and SSE remove that latency and waste at the cost of managing a long-lived connection, reconnection logic, and, for WebSockets, a bidirectional message protocol.

  • SSE is simpler than WebSockets when only server-to-client push is needed.
  • Reconnection and missed-message recovery must be designed explicitly for push mechanisms.
  • Connection-based approaches introduce server-side connection-count scaling considerations.

QAInterview questions and model answers

Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.

Intermediate · Conceptual · 1 min · Question 1What problem does over-fetching describe, and which style tends to cause it?Open model answer

Model answer

Over-fetching is receiving more fields than a screen needs, wasting bandwidth and parsing time. REST endpoints returning a fixed resource shape commonly cause it when different consumers need different subsets of the same resource.

Open question page →
Intermediate · Conceptual · 1 min · Question 2Why isn't a GraphQL response as cacheable at the HTTP layer as a REST GET?Open model answer

Model answer

Most GraphQL traffic goes over POST to a single endpoint with a query body, so URL-based HTTP and CDN caching doesn't apply directly; caching typically requires a dedicated layer such as persisted queries or a normalized client cache.

Open question page →
Intermediate · Conceptual · 1 min · Question 3What is the difference between WebSockets and Server-Sent Events?Open model answer

Model answer

WebSockets provide a full-duplex channel where both sides can send messages at any time. SSE is a simpler one-way channel where only the server pushes events to the client over a long-lived HTTP connection.

Open question page →
Intermediate · Conceptual · 1 min · Question 4Why might a system use REST, GraphQL, and WebSockets together?Open model answer

Model answer

Each solves a different problem: REST or GraphQL for typical request/response reads and writes, and a WebSocket or SSE channel specifically for the subset of data that must update in real time, like a live order status.

Open question page →
Intermediate · Conceptual · 1 min · Question 5What is a common failure mode of polling as a substitute for push?Open model answer

Model answer

Polling wastes requests when nothing has changed and introduces latency up to the poll interval when something has. It also scales poorly since load grows with the number of clients regardless of actual update frequency.

Open question page →
Intermediate · Conceptual · 1 min · Question 6What does GraphQL's N+1 problem refer to?Open model answer

Model answer

Resolving nested fields naively can issue one database or service call per parent record inside a loop. A batching layer such as DataLoader coalesces those calls into a single batched request per level.

Open question page →
Advanced · Conceptual · 1 min · Question 7What is HATEOAS in the context of REST?Open model answer

Model answer

It is the idea that a REST response includes links describing available next actions, so a client can navigate the API dynamically rather than hardcoding every URL structure. Few real-world APIs implement it fully.

Open question page →
Advanced · Conceptual · 1 min · Question 8How does a GraphQL client typically avoid re-fetching data it already has?Open model answer

Model answer

A normalized client cache such as Apollo or Relay stores entities by type and id, so a query for a record already in the cache can be served instantly and merged as new fields arrive.

Open question page →
Advanced · Conceptual · 1 min · Question 9What causes a WebSocket connection to need reconnection logic?Open model answer

Model answer

Network interruptions, server restarts, or proxy timeouts can drop the connection silently; a robust client detects the close event and reconnects with backoff, often resynchronizing state after reconnecting.

Open question page →
Intermediate · Conceptual · 1 min · Question 10Why is a WebSocket less suitable for simple, infrequent request-response calls?Open model answer

Model answer

It requires maintaining an open connection and a message-based protocol for what could be a single stateless request, adding server-side connection management overhead without a real benefit.

Open question page →

SCScenario questions

Scenario 1

A live sports score app currently polls a REST endpoint every 3 seconds for hundreds of thousands of concurrent users.

  1. Identify that the traffic is dominated by unchanged-state responses.
  2. Replace polling with a push mechanism such as SSE or WebSockets.
  3. Consider whether every client needs bidirectional communication or just server push.
  4. Plan for reconnection and missed-update recovery.
Reveal worked answer

Since updates only flow server to client, I would choose SSE over a full WebSocket to keep the implementation and infrastructure simpler, and because SSE reconnects automatically. I would design the payload to include a sequence number so a reconnecting client can request anything missed instead of assuming continuity.

Verify and go deeper