Resources and URLs

Topics in this section
2 cards

Resources, not actions

An HTTP API is easiest to use when its URLs name resources (things) and the HTTP method says what to do with them. A collection holds many items: /orders. An item is one of them, addressed by its id: /orders/42. The same URL is used to read, change and delete that order; only the method changes.

The classic mistake is putting the action in the path: /getOrder?id=42, /createOrder, /orders/42/delete. Each action becomes a new URL to learn, and generic tools (, proxies, client libraries) can't tell which calls are safe to repeat. Use plural nouns, keep ids in the path, and leave verbs to the method.

In real life

GitHub's API: GET /repos/{owner}/{repo}/issues lists issues, POST to the same URL creates one, GET /repos/{owner}/{repo}/issues/7 reads issue 7.

In code: HTTP
GET    /orders          list orders
POST   /orders          create an order
GET    /orders/42       read order 42
PATCH  /orders/42       change some fields of order 42
DELETE /orders/42       delete order 42

Not this:
GET  /getOrder?id=42
POST /createOrder
POST /orders/42/delete
  • The collection and the item are two URLs; five operations share them.
  • Query strings are for filtering a collection (?status=paid), not for naming the item.
Check yourself

Which of these URLs follow resource-oriented design? (Choose two.)

Select 2, then check.

Nesting and relationships

When one resource belongs to another, the path can show it: /customers/7/orders lists the orders of customer 7. Nesting is useful for a collection scoped to a parent. It stops being useful past one level: /customers/7/orders/42/items/3 forces the client to know the customer and the order just to reach an item.

A common rule: nest one level for 'the X of this Y', and give every item its own top-level URL as well, /orders/42, so it can be reached by id alone. Filters are the other way to express a relationship: GET /orders?customer_id=7 returns the same set as /customers/7/orders.

In real life

Stripe uses flat top-level resources with filters: GET /v1/charges?customer=cus_123. GitHub nests one level under the repository: /repos/{owner}/{repo}/pulls.

Check yourself

An API has customers, their orders, and the items in each order. Which designs are reasonable? (Choose two.)

Select 2, then check.