Skip to content

Resource-Oriented Design

A REST API is modeled as collections of individually-addressable resources:

  • Resources are the nouns of the API (e.g., books, channels, players)
  • Resources are referenced with their resource names (URIs)
  • Resources are manipulated via a small set of methods (HTTP verbs)

The standard HTTP methods for REST APIs are: GET, POST, PUT, PATCH, and DELETE.


When designing a REST API, follow this systematic workflow:

  1. Determine resource types: Identify what types of resources your API provides
  2. Determine relationships: Define how resources relate to each other
  3. Decide naming schemes: Establish resource name conventions based on types and relationships
  4. Decide resource schemas: Define resource representations (JSON structure)
  5. Assign methods: Map HTTP methods to each resource

A resource is any piece of data or functionality that clients need to interact with. Resources are the fundamental building blocks of a RESTful API.

A resource-oriented API is modeled as a resource hierarchy (a tree-like structure). Each node is either:

Node TypeDescriptionExample
Singleton ResourceA single, specific instance (leaf node)/books/1, /users/123/profile
Collection ResourceA group of resources of the same type (branch node)/books, /users/123/orders

A singleton resource represents a single, specific instance of something.

GET /api/books/1 # A specific book
GET /api/users/123 # A specific user
GET /api/users/123/profile # User's profile (one-to-one)

Characteristics:

  • Represents one specific thing
  • Has a unique identifier
  • Contains detailed information about that item
  • May have its own sub-resources

A collection resource contains a list of resources (items) of the same type.

GET /api/books # All books
GET /api/users # All users
GET /api/orders # All orders

Characteristics:

  • Contains multiple resources of the same type
  • Returns a list or array of items
  • Supports create operations (POST)
  • Can be paged, sorted, and filtered

A sub-collection is a collection that belongs to a parent resource.

GET /api/books/1/authors # All authors of book 1
GET /api/users/123/orders # All orders by user 123
GET /api/projects/5/tasks # All tasks in project 5

Characteristics:

  • Express relationships between resources
  • Show ownership or containment
  • Provide scoped access to related data

Each sub-resource can be either:

  • An instance resource (leaf): /books/1/authors/3
  • A collection resource (branch): /books/1/authors

A resource model defines what resources your API exposes, what actions can be performed on them, and how they relate to each other. Think of it as translating your application’s data (like database tables or domain objects) into the resources and URLs that clients will interact with.

The diagram below illustrates the aforementioned concepts of in a RESTful API.

Rest Resource Model


Resources model objects from the application data model and almost always have relationships to other resources. These relationships are often modeled using sub-resources.

Relation TypeResourcesMeaning
Independent/projects, /tasksTasks can exist with or without a project
Dependent/projects, /projects/{id}/tasksTasks must belong to a project instance
Associative/users, /projects/{id}/collaboratorsUsers assigned to a project become collaborators

ConditionExample
Child depends on parentMission crew depends on mission
Child belongs to parentMoons belong to a planet
Child lifecycle tied to parentOrder items tied to order
GET /api/missions/apollo-11/crew # Crew exists within mission context
POST /api/planets/jupiter/moons # Add moon to Jupiter

ConditionExample
Resources exist independentlyAstronauts exist without missions
Many-to-many relationshipsAstronauts on multiple missions
Relationships change frequentlySpacecraft reassignments
GET /api/astronauts/neil-armstrong
{
"id": "neil-armstrong",
"name": "Neil Armstrong",
"current_mission": "apollo-11",
"_links": {
"self": "/api/astronauts/neil-armstrong",
"current_mission": "/api/missions/apollo-11",
"all_missions": "/api/astronauts/neil-armstrong/missions"
}
}

GET /{resource}/{resource-id}/{sub-resource}
GET /{resource}/{resource-id}/{sub-resource}/{sub-resource-id}
POST /{resource}/{resource-id}/{sub-resource}

Examples:

# Get all authors of a specific book
GET /api/books/1/authors
# Get a specific author of a specific book
GET /api/books/1/authors/3
# Add an author to a book
POST /api/books/1/authors

Collection resources support various operations to manage and retrieve data efficiently.

OperationHTTP MethodURI PatternDescription
List allGET/resourcesRetrieve all items in collection
CreatePOST/resourcesAdd a new item to collection
Get oneGET/resources/{id}Retrieve a specific item
UpdatePUT/resources/{id}Replace an entire item
Partial updatePATCH/resources/{id}Modify specific fields
DeleteDELETE/resources/{id}Remove an item

Collections can be:

  • Paginated: Return results in manageable chunks
  • Sorted: Order results by specific fields
  • Filtered: Return only items matching criteria
# Paginated request
GET /api/books?page=2&limit=20
# Sorted request
GET /api/books?sort=title:asc
# Filtered request
GET /api/books?filter=genre:fiction
# Combined
GET /api/books?page=1&limit=10&sort=published_date:desc&filter=author:Tolkien

For detailed implementation guidance, see:


ScenarioResource TypeExample
Single configuration/settingsSingleton/users/123/profile
List of similar itemsCollection/products
Items belonging to a parentSub-collection/orders/5/items
One-to-one relationshipSingleton sub-resource/planets/earth/atmosphere
One-to-many relationshipSub-collection/users/123/posts

Use hierarchical (sub-resources) when:

  • Clear ownership/containment relationship exists
  • Child cannot exist without parent
  • You need scoped access to related data
/projects/123/tasks/456 # Task 456 belongs to project 123

Use flat resources when:

  • Resources can exist independently
  • Resources are shared across multiple parents
  • Deep nesting would become unwieldy
/tasks/456 # Task exists independently
# Response includes: { "project_id": 123, ... }

Keep URI hierarchies shallow (2-3 levels maximum):

# Good - clear and manageable
/universities/123/departments/456
# Avoid - too deep
/universities/123/departments/456/courses/789/students/101/grades

For detailed coverage of HTTP methods, see HTTP Verbs. For status codes, see HTTP Status Codes.

Resource-oriented design focuses on:

  1. Identifying resources (nouns) rather than actions
  2. Organizing resources in a logical hierarchy
  3. Using standard HTTP methods for operations
  4. Following consistent naming conventions

This approach creates APIs that are:

  • Intuitive: Easy to understand and use
  • Consistent: Predictable behavior across endpoints
  • Scalable: Easy to extend with new resources
  • Cacheable: Leverages HTTP caching mechanisms