RESTAPIsHTTP

REST APIs, explained with a library, a cart, and a network tab

REST is a set of rules for how programs ask each other for things. Here's what actually matters: resources, methods, status codes, and statelessness.

WebPrims Team11 September 20267 min read
REST APIs, explained with a library, a cart, and a network tab

Every June, a student in our web batch opens the browser's network tab and says, "So the server just sends a text file?" They're looking at a JSON response — a long string of curly braces and colons. They're not wrong. The server did send text. The real question is why the text has the shape it has, and who decided that shape.

The short answer: a set of rules called REST. It's not software, not a library, not a tool you install. It's a list of constraints that two programs agree to follow when one asks the other for something. REST was described by Roy Fielding in his doctoral dissertation in 2000, and it has quietly become the default way most web services talk to each other.

This post explains the few pieces of REST that actually matter in practice: resources, HTTP methods, status codes, and statelessness. We'll use a small library API as a running example.

Resources are the nouns

The core idea in REST is the resource. A resource is a thing — a book, a student, an order, a user. It is not a page, not a screen, not a file. The API exposes resources, and every resource has an address.

In a library API, the resources are books and authors:

  • /books — the collection of all books
  • /books/7 — the book with ID 7
  • /authors/3/books — all books written by author 3

Notice the pattern. Nouns, not verbs. We do not write /getBook?id=7 or /deleteBook. The URL names the thing; the action is handled separately, by the HTTP method. This separation is what makes REST easy to read. When you see a URL, you know what it points to, but you cannot tell what is happening to it until you know the method.

A common beginner mistake is to put actions in the URL: /createUser, /updateUser. It works, but it defeats the purpose of REST. The URL should stay stable, and the same URL should mean the same resource regardless of what you do with it.

HTTP methods are the verbs

HTTP gives us a small set of verbs. In practice, most REST APIs use five of them:

  • GET — fetch a resource. Safe, meaning it changes nothing.
  • POST — create a new resource. The new resource's URL is typically returned in the response.
  • PUT — replace a resource completely with what you send.
  • PATCH — update only the fields you send.
  • DELETE — remove a resource.

The difference between PUT and PATCH trips up people for weeks. PUT sends the whole resource and says "make it exactly this." PATCH sends only the changed fields and says "change these parts." If a book has a title, an author, and a year, a full update via PUT sends all three. A PATCH might send only the year.

Here's what these look like with curl, a command-line tool that sends HTTP requests:

# Fetch the book with ID 7
curl https://api.library.example/books/7

# Create a new book
curl -X POST https://api.library.example/books \
  -H "Content-Type: application/json" \
  -d '{"title":"The Left Hand of Darkness","authorId":3,"year":1969}'

# Update the year of book 7 (partial update)
curl -X PATCH https://api.library.example/books/7 \
  -H "Content-Type: application/json" \
  -d '{"year":1970}'

GET and DELETE are idempotent: calling them ten times has the same effect as calling them once. POST is not — every call creates a new resource. PUT and PATCH are idempotent in theory, though PATCH is only idempotent if the operation itself is designed that way. This matters for retries: if a request times out, you can safely retry an idempotent one.

Status codes tell you what happened

The server answers every request with a three-digit status code. The codes are grouped by their first digit:

  • 2xx — success
  • 4xx — the client made a mistake
  • 5xx — the server made a mistake

Within these ranges, a handful of codes cover most situations. 200 OK is the standard success response for GET, PUT, and PATCH. 201 Created is the response to a POST that created something; it should include a Location header pointing to the new resource. 204 No Content is a success with an empty body, often returned after a DELETE. On the error side, 400 Bad Request means the request was malformed — bad JSON, missing field. 401 Unauthorized means you haven't authenticated. 403 Forbidden means you have authenticated but aren't allowed to do this. 404 Not Found means the resource doesn't exist. 500 Internal Server Error is the server's "I don't know what happened" response.

The codes are not decoration. They are the contract. A well-built client checks the code first and only then reads the body. A badly built client checks the body and guesses. We have seen students spend an hour debugging a 404 they thought was a "no results" response, because their code never looked at the status.

Statelessness is the hard part

The constraint that confuses people most is statelessness. It means the server does not remember you between requests. Each request must carry everything the server needs to understand it.

Consider a shopping cart. In a stateful design, you add an item to your cart on the server, and the server remembers the cart for your session. In a stateless REST design, you send the whole cart — or the item you want and the quantity — in every request. The server processes each request on its own, with no memory of the previous one.

This sounds inefficient, and sometimes it is. But it has a huge payoff: any server can handle any request. Since no server holds a "conversation" state, you can put many servers behind a load balancer, and it does not matter which one receives your request. You can take servers down for maintenance without breaking in-progress conversations, because there are no in-progress conversations. This is why statelessness is not a design preference but a constraint: it is what makes web services scalable.

In practice, statelessness shows up in authentication. Instead of a session cookie that the server looks up, a REST client sends a token with every request, usually in an Authorization header. The server verifies the token, does the work, and forgets the client.

What REST is not

Three confusions come up every batch.

First, REST is not JSON. JSON is just a data format. REST is about the arrangement of URLs, methods, and codes. You can have a REST API that returns XML, and you can have a JSON API that follows none of the REST constraints.

Second, REST is not HTTPS. HTTPS is encryption on top of HTTP. REST describes how the HTTP request and response are structured, not how they are secured.

Third, most "REST APIs" are not fully REST. Fielding's dissertation lists six constraints, and very few APIs implement all of them. What most people call a REST API is really an HTTP API that uses URLs, methods, and status codes in a sensible way. That is fine. The name is used loosely, and arguing about it is not useful. What matters is that you understand the underlying ideas, because those ideas are what make the API predictable.

When you design an API, the practical questions to ask are: What are my resources? What are the actions on each resource? What should the status codes say? And what does each request need to carry so that no server has to remember anything?

Common questions

Why do some APIs put /api/v1 at the start of the URL?

It is versioning. Once an API is released, other developers write code against it. If you change the shape of the response or the meaning of an endpoint, you break that code. Putting a version in the URL lets you change the API freely under /api/v2 while the old /api/v1 keeps working for existing clients. Some teams version with headers instead, but the URL approach is the most visible and the easiest to reason about.

What is the difference between REST and GraphQL?

They solve the same problem — letting a client request data from a server — but in different ways. REST exposes a fixed set of endpoints, each returning a fixed shape of data. GraphQL exposes a single endpoint, and the client writes a query describing exactly which fields it wants. GraphQL avoids the problem of fetching too much or too little data, but it requires more setup on the server and makes caching harder. For a small API with a few resources, REST is usually simpler.

Is it okay if my API only supports GET and POST?

Yes. Many real-world APIs use only these two. The REST constraints describe a style, not a checklist. If you do not need partial updates, you do not need PATCH. If you never replace a whole resource, you do not need PUT. What matters is that the methods you do use are used consistently, and that your API does not surprise

Come and sit a class before you decide

Reading about it only gets you so far. Pick a day, sit in on a class that is already running, write some code, and talk to the students in it. Free, and nothing to pay afterwards unless you want to join.

RESTAPIsHTTP

Found this useful?

Share it with someone who is learning.

CallWhatsAppFree demo