2026-08-21 14:47:46.324577+08 / restful-api

Resources

Guidelines for business resource modeling, naming, hierarchy, and identifier design in RESTful APIs.

Restful ApiApi DesignOpenapi

Resources

Model the Business Domain

An API should model the business domain and expose resources that represent meaningful business concepts.

Resources should contain the necessary information required by API consumers while avoiding exposing internal implementation details.

A well-designed resource model provides:

  • Clear understanding of the business domain
  • Consistent resource representation
  • Reduced coupling between clients and services
  • Better API evolution capability

APIs should not be designed as simple wrappers around database tables. Business concepts and domain logic should be represented through meaningful resources instead of exposing persistence models directly.

For complex domains, different models may exist depending on the business context. The applicable context should always be clearly defined.


Define Useful Resources

Resources should be designed to cover the majority of client use cases.

A useful resource should:

  • Contain enough information for common scenarios
  • Avoid unnecessary data exposure
  • Provide flexibility through filtering, pagination, or embedding mechanisms

The goal is to provide a balanced resource representation:

  • Too little information forces clients to make unnecessary API calls.
  • Too much information increases payload size and coupling.

Avoid Actions in Resource URLs

REST APIs should be resource-oriented.

Actions should be represented by HTTP methods rather than verbs in URLs.

Use:

text

POST /orders
GET /orders/{id}
PUT /orders/{id}
DELETE /orders/{id}

Avoid:

text

POST /orders/create
POST /orders/{id}/cancel
POST /orders/{id}/approve

The URL should represent a resource, while the HTTP method represents the operation.

Modeling Actions as Resources

When an operation represents a business event or state transition, model it as a resource.

Example:

Instead of:

text

POST /vehicles/{vehicleId}/lock

Use:

text

PUT /vehicles/{vehicleId}/doors-lock

{
"lockStatus": "locked"
}

or:

text

POST /vehicles/{vehicleId}/door-actions

{
"type": "unlock"
}

This approach provides better extensibility because actions can later become persistent resources with:

  • timestamps
  • audit information
  • history queries
  • additional metadata

Model Complex Operations as Resources

For complex operations requiring multiple parameters, create dedicated resources.

Example:

Instead of:

text

POST /vehicles/move

Use:

text

POST /vehicle-transfers

{
"sourceOrganizationId": "org-a",
"targetOrganizationId": "org-b",
"vehicles": [
"vehicle-1",
"vehicle-2"
]
}

This creates a resource representing the transfer operation and enables:

  • Tracking operation status
  • Auditing historical operations
  • Supporting asynchronous processing

Use Domain-Specific Resource Names

Resource names should represent business concepts.

Good:

text

/sales-orders
/customers
/payment-transactions

Avoid generic names:

text

/items
/data
/entities
/objects

Domain-specific names improve:

  • API readability
  • Developer understanding
  • Documentation quality

Use URL-Friendly Resource Identifiers

Resource identifiers used in URLs should contain only URL-safe characters.

Recommended characters:

text

A-Z
a-z
0-9
---

_
:
.

Avoid identifiers requiring additional encoding.

Example:

Good:

text

/customers/customer_123

Avoid:

text

/customers/customer name with spaces

Identify Resources and Sub-Resources Through Path Segments

Resources and sub-resources should be represented using URL path segments.

General structure:

text

/resources/{resource-id}/sub-resources/{sub-resource-id}

Examples:

text

/customers/123
/customers/123/addresses
/customers/123/addresses/home

A valid resource path should generally imply that parent resources also exist.

For example:

text

/customers/123/addresses/home

should imply:

text

/customers
/customers/123
/customers/123/addresses

Composite identifiers should not use / as separators.


Use UUIDs Only When Necessary

UUIDs are useful for distributed systems where identifiers must be generated independently without coordination.

However, UUIDs have disadvantages:

  • Difficult for humans to read and remember
  • Less convenient for debugging
  • Larger storage and network overhead
  • No natural ordering
  • Less suitable for user-facing identifiers

Use UUIDs mainly when:

  • High-scale distributed ID generation is required
  • Multiple systems generate IDs independently
  • Collision avoidance is critical

For simple business entities, server-generated identifiers may be preferred.

Regardless of identifier type:

  • IDs should be represented as strings
  • IDs should remain stable after creation
  • IDs should not be reused

Limit Resource Types

APIs should avoid exposing too many unrelated resource types.

A resource type represents a group of closely related resources:

Example:

text

/customers
/customers/{id}
/customers/{id}/addresses
/addresses

Well-designed APIs typically contain a limited number of resource types.

If an API exposes many unrelated resources, consider splitting the API based on business domains or bounded contexts.


Limit Sub-Resource Nesting Levels

Nested resources should only be used when the lifecycle of the child resource is strongly related to the parent resource.

Recommended:

text

/customers/{id}/orders/{orderId}

Avoid deeply nested structures:

text

/customers/{id}/orders/{orderId}/items/{itemId}/details/{detailId}

Deep nesting causes:

  • Complex URLs
  • Difficult API discovery
  • Increased coupling

As a guideline, limit nesting depth to approximately three levels.


Summary

A well-designed REST API should:

  • Model business concepts instead of database structures
  • Use nouns instead of verbs in URLs
  • Represent complex operations as resources
  • Use meaningful domain-specific resource names
  • Keep identifiers URL-friendly
  • Use UUIDs only when required
  • Avoid excessive resource types
  • Avoid deep resource nesting

The goal is to create APIs that are predictable, understandable, extensible, and easy for clients to consume.

Resources | Remi Resume