REST API Design Best Practices

Chapter 1 · Practice 3 of 4

Model operations that are not CRUD as sub-resources or state changes

From Resources and URLs

Why it matters

Some operations do not map neatly onto create, read, update and delete: cancelling an order, refunding a payment, resending an email. Two patterns keep them RESTful without inventing verbs in every path:

  1. A state change on the resource: PATCH /orders/7 with {"status": "cancelled"}, when the operation really is just a field change.
  2. A sub-resource that represents the action or its result: POST /payments/42/refunds creates a refund. The refund then has its own URL and history.

When neither fits, a clearly named action endpoint such as POST /orders/7/cancel is acceptable. Use POST for it, document it, and use the same pattern everywhere.

Example

HTTP
POST /payments/42/refunds
Content-Type: application/json

{ "amount": "15.00", "currency": "USD", "reason": "damaged_item" }

HTTP/1.1 201 Created
Location: /payments/42/refunds/9