Designing a RESTful API
Turning data into a clean, predictable set of URLs and verbs
- model data as resources and design their URLs,
- map HTTP verbs to create/read/update/delete, and know which are safe or idempotent,
- return the right status codes for success and failure,
- explain why REST is stateless and design around it.
1. Resources: model nouns, not actions
The heart of REST is the resource: a thing your system knows about, such as a task, a user, or an order. A resource is a noun. The mistake beginners make is designing around verbs — /createTask, /getTask, /deleteTask — which means every new action needs a new URL and every client must memorise them.
In REST you flip that around. You expose one URL per resource and let the HTTP method describe the action:
- a collection lives at a plural path:
/tasks - a single item lives under it by id:
/tasks/42
Analogy. Think of a filing cabinet. /tasks is the drawer labelled "Tasks"; /tasks/42 is one folder inside it. You never label a drawer "open the tasks drawer" — the drawer is a noun, and opening, adding, or removing folders are separate actions you perform on it. HTTP verbs are those actions.
2. HTTP verbs: one method, one intent
HTTP defines a small set of verbs, each with an agreed meaning. A well-designed API uses them exactly as intended so clients, proxies, and caches can reason about a request without reading its body.
| Verb | Typical use | On /tasks | On /tasks/42 |
|---|---|---|---|
| GET | Read | list all tasks | fetch task 42 |
| POST | Create | create a new task | (rarely used) |
| PUT | Replace | (rarely used) | replace task 42 wholesale |
| PATCH | Partial update | (rarely used) | change some fields of task 42 |
| DELETE | Remove | (rarely used) | delete task 42 |
Two properties matter when choosing a verb:
- Safe — the request does not change server state.
GETis safe; it should never create or delete anything. This is why a browser can prefetch links freely. - Idempotent — sending the same request twice leaves the server in the same state as sending it once.
GET,PUT, andDELETEare idempotent;POSTis not (two POSTs create two tasks).
PUT vs PATCH trips people up: PUT replaces the whole resource (fields you omit are cleared), while PATCH changes only the fields you send. Choose PATCH when a client wants to flip one flag without resending the entire object.