Warming up the neural circuits...
By the end of this chapter you will:
An API is the contract that lets two programs work without either knowing how the other is built. Without it, every app would have to be rewritten every time anything changed.
A McDonald's drive-through has a small, well-defined contract:
You don't need to know who the cook is, where the meat comes from, or what software the cash register runs. You just need to know the contract. Tomorrow they can fire the cook, switch suppliers, replace the register — and you can still get a Big Mac.
An API is that contract for software.
API = Application Programming Interface. The official definition is "a set of definitions and protocols for building software." That's correct and useless.
The simple version: an API is a list of URLs your program can call, with rules about what each one does.
You've already used APIs:
GET https://api.github.com/users/torvalds returns Linus Torvalds' GitHub profile as JSON.POST https://api.stripe.com/v1/charges creates a payment.GET https://api.openweathermap.org/data/2.5/weather?q=Mumbai returns Mumbai's weather.Every backend you build is an API. You're publishing a list of URLs the frontend (or other backends) can call.
In the early 2000s the web tried lots of API styles — SOAP, XML-RPC, CORBA. They all lost to REST because REST was just the web already. is not a protocol. It's a philosophy. Five rules:
That's it. That's REST.
GET /api/users # list all users
GET /api/users/42 # one user
POST /api/users # create
PATCH /api/users/42 # update
DELETE /api/users/42 # remove
GET /api/users/42/posts # all posts of user 42Notice the nouns. No /getUser, no /createUser, no /deleteUserById. The HTTP method is the verb. The URL is the noun. This is the whole game.
If you see verbs in URLs — /getUser, /checkOrderStatus, /uploadAvatarV2 — the API is not REST. It might still be fine, but call it what it is: RPC-over-HTTP.
Methods and status codes are easy. Naming resources is hard. Three rules to start:
/users, not /user. Even for a single resource — you're navigating a collection./users/42/posts is fine. /users/42/posts/3/comments/8/replies/2/likes is misery./posts?author=42&status=published, not /posts/by-author/42/status/published.What about non-resource actions? You'll occasionally want POST /payments/123/refund. That's fine — purists complain, real developers ship.
You will hear these three names a lot. Quick comparison:
| REST | gRPC | ||
|---|---|---|---|
| Format | JSON over HTTP | JSON over HTTP | Protobuf over HTTP/2 |
| Endpoints | Many (one per resource) | One (/graphql) | Many (RPCs) |
| Client picks fields? | No | Yes | No |
| Best for | Public APIs, simple | Complex frontends with many shapes | Service-to-service |
| Tooling | Universal | Decent | Excellent (typed) |
| Learning curve | Lowest | Highest | Medium |
For your first 5 years as a backend dev, REST is the right choice 80% of the time. Master it before you reach for the others.
JSON = Object Notation. Despite the name, every language can read it. Two shapes:
{
"id": 42,
"name": "Aditi",
"tags": ["backend", "node"],
"isAdmin": false,
"joinedAt": "2024-08-12T11:23:45Z",
"address
[1, 2, 3, "four", { "five": 5 }]Rules:
"double quotes". Single quotes break it.{"a": 1,} is invalid JSON."id", not id.JSON numbers are double-precision floats. They lose precision above 2⁵³. So if you're sending bigint IDs:
{"id": 9007199254740993}This will be parsed by JS as 9007199254740992. Subtle one-off bug, hours to find.
Fix: send big IDs as strings, or use a JSON parser that supports BigInt.
Here's how a well-designed user resource might look:
# List
GET /api/users?limit=20&cursor=...
→ 200 OK
{
"data": [{...}, {...}],
"nextCursor": "abc123"
}
# Read one
GET /api/users/42
→ 200 OK
{"id": 42,
Notice:
limit + cursor, not page numbers.201 and a Location header pointing at the new resource.204 (no body).| Mistake | Why it's wrong | What to do |
|---|---|---|
Verbs in URLs (/getUser) | Defeats the verb–noun separation | Use methods + plural nouns |
| Returning 200 on errors | Tooling can't tell success from failure | Use 4xx / 5xx with a JSON error body |
| Inconsistent casing in JSON | Sometimes camelCase, sometimes snake_case | Pick one. Stick to it. (camelCase is most common in JS APIs.) |
| Putting auth tokens in query strings | Logged everywhere | Use Authorization: Bearer ... |
| Returning bigint IDs as JSON numbers | Precision loss above 2⁵³ | Return as strings |
Production. Version your API from day one. /api/v1/.... When you need to break a contract, you'll have somewhere to land.
Performance. Return only what the client needs. A GET /users/42 shouldn't return their entire order history.
Security. Field-level authorization matters. A logged-in user shouldn't see other users' emails just because they ask GET /users/123. Decide what's public per-field, not per-endpoint.
https://docs.github.com/en/rest. Find five GET endpoints and call them with curl./api/getAllUsers) and rewrite it as REST.Beginner. What's the difference between PUT and PATCH? PUT replaces the whole resource; PATCH modifies parts.
Senior. When would you choose GraphQL over REST? When clients need many different shapes of the same data and you want to avoid over- or under-fetching. Cost is complexity.
An API is a published contract. REST is the dominant style on the web: resources as nouns, HTTP methods as verbs, JSON as the wire format, status codes as the outcome. Design URLs by resource, version from day one, and you'll have an API that lasts decades.
/api/getUserById?id=42?DELETE use?