REST APIs
The architectural style that powers Stripe, GitHub, Twitter, your weather app, and basically the internet.
Begin →A hands-on tour through REST APIs — the lingua franca of the web — and the Model Context Protocol — how AI assistants talk to the world. Read short lessons, click through real examples, simulate live requests, and prove you got it with quizzes.
The architectural style that powers Stripe, GitHub, Twitter, your weather app, and basically the internet.
Begin →The open standard that lets AI applications plug into tools, data, and workflows — like USB-C for AI.
Begin →Build sample requests, simulate JSON-RPC handshakes, and put your knowledge to the test.
Open →Before we dive in, here's the minimum vocabulary you need.
REST (REpresentational State Transfer) is an architectural style for building networked applications, introduced by Roy Fielding in his 2000 dissertation. It is not a protocol or a standard — it's a set of constraints that, when followed, produce systems that are simple, scalable, and reliable.
Most "REST APIs" you'll meet in the wild are HTTP APIs that follow most of these constraints. The pattern is the same everywhere: a client sends an HTTP request to a URL identifying a resource, using an HTTP method that describes the intent, and gets back a representation (usually JSON).
GET /api/users/42 HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGciOi...
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=60
{
"id": 42,
"name": "Ada Lovelace",
"email": "ada@example.com",
"_links": {
"self": { "href": "/api/users/42" },
"orders": { "href": "/api/users/42/orders" }
}
}
A REST request is just method + URL + headers (+ body). The response is status + headers + body. Everything else in this module is detail on those four moving parts.
Click any constraint to expand the explanation. Five are required for "RESTful"; one is optional.
One consistent way to identify, manipulate, and describe resources. In an HTTP-based REST API this means standard URIs, standard methods (GET/POST/PUT/DELETE), self-descriptive messages (headers like Content-Type), and ideally HATEOAS — responses contain links that drive what the client can do next.
The client (UI/UX) and the server (data/business logic) evolve independently. As long as the contract — the API — stays stable, either side can change without breaking the other. This is what lets you have web, iOS, Android, and CLI clients all hitting the same backend.
Each request from a client carries everything the server needs to understand it. The server stores nothing between requests. This makes the system massively scalable: any server in a fleet can answer any request. (Application state lives in the client; resource state lives in databases.)
Responses declare their cacheability via headers like Cache-Control, ETag, and Expires. Smart caching is one of the reasons the web scales — the response to "give me CNN's homepage" can be served from a CDN to millions of people without ever touching the origin server.
You can stack proxies, gateways, load balancers, and caches in front of the actual server. The client only sees the outer layer. This lets architects add security boundaries, scale horizontally, and migrate backends invisibly.
The only optional constraint. The server can extend client functionality by sending code (the most familiar example: a server returning HTML that includes <script> tags). Useful, but most pure JSON APIs ignore this constraint entirely.
Memorize the acronym U-S-C-L-C: Uniform interface · Stateless · Cacheable · Layered · Client-server. Code on demand is optional. Most production APIs ignore HATEOAS, technically making them "RESTish" rather than fully RESTful — and that's fine for most use cases.
Tap a method to see what it does, when to use it, and a real example. Defined in RFC 9110.
You only need four methods 90% of the time: GET reads, POST creates, PUT/PATCH update (replace vs. partial), DELETE removes. HEAD/OPTIONS are utility methods; TRACE/CONNECT are niche.
Type a status code or pick one from the grid. Each lives in one of five families.
The request succeeded. The resource is returned in the body.
413 Payload Too Large → 413 Content Too Large, and
422 Unprocessable Entity → 422 Unprocessable Content.
Old names still work everywhere; you'll see both in the wild.
Two production-grade concepts that decide whether retrying a request is safe.
Two concepts trip people up constantly. They're easy once you have a mental model.
The method does not change server state. Calling it a million times leaves the world unchanged.
Safe methods: GET, HEAD, OPTIONS, TRACE
Calling the method multiple times has the same final effect as calling it once.
Idempotent: GET, HEAD, OPTIONS, TRACE, PUT, DELETE
All safe methods are idempotent; the reverse is not true.
| Method | Safe? | Idempotent? | Why |
|---|---|---|---|
| GET | ✅ | ✅ | Reads only. Repeating it doesn't change anything. |
| POST | ❌ | ❌ | Creates a new resource each call. |
| PUT | ❌ | ✅ | Sets the resource to a value. Setting it twice still leaves it at that value. |
| PATCH | ❌ | ❌* | Partial update. {"counter": +1}-style patches are NOT idempotent. |
| DELETE | ❌ | ✅ | Resource gone after one call. Calling again → still gone. |
| HEAD | ✅ | ✅ | Headers only — read-only, no state change. |
| OPTIONS | ✅ | ✅ | Capability probe — never alters state. |
Idempotency-Key
header so that retrying a POST /charges after a network hiccup won't charge
the customer twice. Idempotency is one of the most important production concepts in API design.
Safe ⊂ Idempotent. Safe methods (GET, HEAD, OPTIONS, TRACE) never change state. Idempotent methods (add PUT, DELETE) may change state, but repeating them lands the world in the same place. POST and PATCH are neither — add an Idempotency-Key header if you need retry safety on those.
Pick a method, type a URL, add headers and a body. Watch the raw HTTP request build itself.
MCP is an open standard, introduced by Anthropic on November 25, 2024, for connecting AI applications to external systems — data sources, tools, and workflows. Think of it as USB-C for AI: one consistent plug, hundreds of compatible devices.
Without MCP, every AI application needs custom integrations for every external system it wants to use. With MCP, an AI app and a service speak the same protocol, so you "build once and integrate everywhere". The protocol takes direct inspiration from the Language Server Protocol (LSP), which solved the same M-by-N integration explosion for code editors and language tooling.
Adoption since launch: OpenAI (March 2025), Google DeepMind (April 2025),
plus Microsoft, GitHub, Cursor, Sentry, Zed, Replit, and hundreds of community servers.
The current stable spec is 2025-11-25; a release candidate 2026-07-28
introduces a stateless transport and server-rendered MCP Apps.
Build one MCP server and any compatible AI app (Claude, ChatGPT, VS Code, Cursor…) can use it.
Tap into an entire ecosystem of tools, data, and workflows without bespoke integration code.
Smarter assistants that can read your calendar, query your database, and run real actions on your behalf.
MCP is to AI integrations what LSP was to language tooling: a single shared protocol that turns an M × N integration problem (M apps × N services) into M + N.
MCP uses a client-server architecture with three participants. A single AI application (the host) can speak to many MCP servers at once, opening one dedicated client per server:
MCP has two conceptual layers:
stdio for local subprocesses, Streamable HTTP for remote servers (HTTP POST plus optional Server-Sent Events).Host = the app you open. Client = an in-app connector (one per server). Server = the program exposing tools/resources/prompts. Wire data through the data layer (JSON-RPC) over a transport (stdio or Streamable HTTP).
Everything an MCP server can offer reduces to one of these three things. Each has a different control model: who decides when it runs?
Functions the LLM can call to take actions. Search flights, send a Slack message, query a DB.
tools/listtools/call
Read-only data the app pulls in as context. File contents, DB schemas, API docs, calendar entries.
resources/listresources/readresources/subscribe
Pre-built templates the user explicitly picks. Slash commands like /plan-vacation.
prompts/listprompts/get
Servers expose three primitives, each with a different driver: Tools (LLM picks), Resources (app injects), Prompts (user invokes). Memorize the control model — it dictates UX and security policy.
Servers can also ask the client to do things:
The server asks the host's LLM to generate text. Lets servers stay model-agnostic.
sampling/createMessage
The server asks the user for more info or confirmation mid-flow.
elicitation/create
The client tells the server which directories or scopes it can touch.
roots/list
The same JSON-RPC messages flow over one of two transports. Local or remote — that's the choice.
The host spawns the server as a subprocess and communicates over standard input/output. Zero network overhead, ideal for local tools like a filesystem server.
// Host launches server, then talks via stdin/stdout
{
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
}
HTTP POST for requests, optionally with Server-Sent Events for streaming. Supports bearer tokens, OAuth, and standard auth headers. Used by hosted servers like Sentry's MCP.
POST /mcp HTTP/1.1
Host: mcp.sentry.io
Authorization: Bearer sk_live_...
Content-Type: application/json
Accept: application/json, text/event-stream
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
Same protocol, two pipes. Use stdio when the server runs on your machine (filesystem, git, local shell). Use Streamable HTTP when the server lives behind a URL with auth (Sentry, GitHub, Linear, internal SaaS).
Walk through a real MCP client-server conversation, message by message. Click Next step to advance.
Print-friendly summary of everything in both modules.
Cache-Control, ETag, If-None-Match → 304.Idempotency-Key header.2025-11-25; next RC 2026-07-28.tools/list, resources/list, prompts/list.| Aspect | REST API | MCP |
|---|---|---|
| Purpose | App ↔ server communication | AI app ↔ tools/data communication |
| Wire format | HTTP + JSON (usually) | JSON-RPC 2.0 over stdio or HTTP |
| Identification | URLs (resources) | Method names + primitive IDs |
| Discovery | Out-of-band (OpenAPI, docs) | In-protocol (*/list at runtime) |
| State | Stateless (per request, by constraint) | Stateful today (2025-11-25); stateless RC ships 2026-07-28 |
| Auth | Anything HTTP allows (Bearer, OAuth, mTLS, API keys…) | OAuth 2.1 + OIDC for remote; client-managed for stdio |
| Streaming | SSE / WebSockets (bolted on) | First-class via notifications / SSE |
| Designed for | Humans + apps | LLMs + apps |
| Year introduced | 2000 (Fielding) | Nov 25, 2024 (Anthropic) |
Fire a real GET request against a public, no-auth API (JSONPlaceholder). Inspect the live response.
// Click "Send request" to fetch real data
23 questions across both modules. No time limit. Pass = 80%. Each answer comes with an explanation.