REST in Practice
Resources, URLs, and HTTP Methods
In the previous post, I covered what REST is and where it came from. Now let's look at how it actually works. This is where the principles become concrete.

Resources and URLs
REST APIs are built around resources. A resource is anything the API exposes: a user, a book, an order, a transaction. Each resource has a unique URL that identifies it.
Consider a bookstore API. It has a database of books:
| ID | Title | Author | Published Year |
|---|---|---|---|
| 991 | The Great Gatsby | F. Scott Fitzgerald | 1925 |
| 992 | The Old Man and the Sea | Ernest Hemingway | 1952 |
Each book is a resource with its own URL:
https://api.example.com/books/991https://api.example.com/books/992
The pattern is consistent: base URL, resource type (plural noun), and identifier. To fetch a book:
curl -X GET https://api.example.com/books/991
The server responds with JSON:
{
"id": 991,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_year": 1925
}
HTTP Methods
HTTP methods define what you can do with a resource. They map to the CRUD operations you'd perform on a database. Getting these right makes an API feel intuitive.
GET retrieves a resource. It's safe (doesn't modify anything) and idempotent (calling it multiple times has the same effect as calling it once).
curl -X GET 'https://api.example.com/users/123'
POST creates a new resource. It's neither safe nor idempotent. Each call typically creates a new record.
curl -X POST 'https://api.example.com/users' \
-d '{"name": "John Doe", "email": "john@example.com"}'
PUT replaces a resource entirely. You send the complete object, and the server swaps out the existing one. It's idempotent: putting the same data twice has the same result as putting it once.
curl -X PUT 'https://api.example.com/users/123' \
-d '{"name": "John Doe", "email": "newemail@example.com"}'
PATCH updates part of a resource. Unlike PUT, you only send the fields you want to change.
curl -X PATCH 'https://api.example.com/users/123' \
-d '{"email": "newemail@example.com"}'
DELETE removes a resource. It's idempotent: deleting something twice has the same effect as deleting it once (the resource is gone either way).
curl -X DELETE 'https://api.example.com/users/123'
HEAD is like GET but returns only headers, no body. Useful for checking if a resource exists or when it was last modified.
OPTIONS describes what methods a resource supports. Browsers use this for CORS preflight requests.
Idempotence and Safety
Two concepts worth understanding, because they've saved me from bugs more than once:
A method is safe if it doesn't modify server state. GET and HEAD are safe. You can call them repeatedly without changing anything.
A method is idempotent if calling it multiple times has the same effect as calling it once. GET, PUT, DELETE, and HEAD are all idempotent. POST is not, because each call might create a new resource.
These properties matter for error handling. If a network request times out, you can safely retry an idempotent method. Retrying a POST might create duplicate records.
Statelessness in Practice
Remember that REST is stateless: each request must contain everything the server needs. There's no session on the server tracking who you are.
In practice, this means authentication tokens travel with every request. The server validates the token, processes the request, and forgets about you. This simplifies scaling because any server can handle any request.
In the next post, I'll cover status codes, security, and best practices for building robust APIs.