Modeling Resources
Before naming a single URI, decide what your resources are. Good resource modeling makes the rest of the API fall into place; poor modeling shows up later as awkward endpoints and special cases.
Find the nouns
Section titled “Find the nouns”Start from the domain language. The persistent things your users talk about — orders, invoices, playlists, devices — are your primary resources. They usually map to collections you create, read, update, and delete.
// The resources of a small blog API, as TypeScript shapes.type User = { id: string; name: string; email: string };type Article = { id: string; title: string; body: string; authorId: string };type Comment = { id: string; body: string; articleId: string; authorId: string };Not every database table is a resource, and not every resource is a table. A resource is anything worth addressing with a URI — including computed or virtual things like /me (the current user) or /search.
Resource, not action
Section titled “Resource, not action”When a use case sounds like a verb — “publish an article”, “cancel an order” — resist inventing /publishArticle. Two cleaner options:
- Model the change as a field update:
PATCH /articles/42with{ "status": "published" }. - Model the action as a sub-resource it creates:
POST /orders/42/cancellation.
Granularity
Section titled “Granularity”Aim for resources that are neither too coarse (one giant /data blob) nor too fine (a separate resource per field). A good test: a resource should be something a client wants to fetch, create, or change as a unit.