Resources & Verbs
16 min
REST models everything as a resource (a noun — /users,
/orders/42) acted on by a small, fixed set of HTTP verbs — instead
of inventing a new endpoint for every action (/getUser, /createUser,
/deleteUser), you use the SAME path with different methods:
def resource_path(resource, id=None):
if id is None:
return f"/{resource}"
return f"/{resource}/{id}"
print(resource_path("users")) # /users -- the collection
print(resource_path("users", 42)) # /users/42 -- one specific user
GET /users lists users, POST /users creates one, GET /users/42
reads user 42, PUT /users/42 replaces it, DELETE /users/42 removes
it — the verb carries the intent, the path just names the resource.
Four completely different operations, only two distinct paths -- the verb is doing the work that a REST-naive API might instead cram into the path itself (/getOrders, /createOrder, etc.).
Idempotent means calling it once has the same effect as calling it
many times. DELETE /users/42 is idempotent — delete a user that's
already gone, and the end state (user 42 doesn't exist) is identical.
POST /users is NOT idempotent — call it twice, and you've created two
users, not one.
def verb_is_idempotent(verb):
return verb in {"GET", "PUT", "DELETE", "HEAD", "OPTIONS"}
This matters enormously for retry logic: if a PUT request times out
and you're not sure whether it went through, it's safe to just retry it
(idempotent — worst case, you set the same value twice). Retrying an
uncertain POST risks creating a duplicate resource — which is exactly
why idempotency is one of the first things worth checking before adding
automatic retries to any API client.
Write `verb_is_idempotent(verb)`: return True if the HTTP method is conventionally idempotent (`GET`, `PUT`, `DELETE`, `HEAD`, `OPTIONS`).
Write `resource_path(resource, id=None)`: return `/{resource}` if `id` is None, otherwise `/{resource}/{id}`.
What does it mean for an HTTP method to be 'idempotent'?
You can build RESTful resource paths and identify which HTTP verbs are safe to retry automatically because they're idempotent.