While CRUD provides a foundational understanding of HTTP verbs, it oversimplifies ReST API design. Many argue that ReST is just CRUD over HTTP, with:
While this analogy seems reasonable and works for most people, it’s worth considering if there’s more to it. Shoehorning A to CRUD overlooks the depth of designing systems that truly serve user intent.
In the first episode of this ReST series, I introduced a key idea:
ReST API design is like scripting a dialogue between two people
The first step in designing a ReST API is deciding on the "language" of the conversation, essentially, the format used to exchange information. Think of it as agreeing beforehand on whether you'll "speak" in:
This ensures that both parties, the user and the system, can understand each other clearly from the outset.
Next, focus on understanding the requirements, which are essentially the user's intentions:
Once you’ve understood the intention:
By treating API design as scripting a meaningful dialogue, you can create systems that feel intuitive, purposeful, and human-centric.
Now that we've established the importance of crafting meaningful dialogues, let’s take the example of order cancellation. At first glance, the user’s intention seems straightforward: they want to cancel the order. A lazy approach might map this action directly to a DELETE
request.
While technically valid, this design overlooks a critical aspect: understanding the “why.”
DELETE /orders/1234
As a business owner, knowing why an order is canceled is invaluable—it opens opportunities to improve services, address customer concerns, and potentially recover the relationship. A simple DELETE
erases the order but loses the chance to ask the customer questions like:
By framing the cancellation process more thoughtfully, perhaps through a POST
to a “CancelledOrders” endpoint with a reason code or message you capture the humane aspect of the dialogue. This way, the API design doesn’t just serve the technical need but also aligns with broader business goals.
POST /CancelledOrders
Content-Type: application/json
{
"orderId": 1234,
"reason": "price too high"
}
CancelledOrders is a noun and at times you might need some time to come up with a meaningful noun. One may come up with a rather odd noun, OrderCanceller, and there is nothing wrong, ReST does not stop one from doing that. By the way this is a classic ReST design dilemma.
Let’s look at these two nouns systematically, balancing opinions and rationale.
This approach treats cancellations as a distinct resource with its own lifecycle, attributes, and state, while keeping the original Order
resource untouched.
Emphasizes nouns/resources over actions, aligning with ReST's guideline of avoiding verbs in URIs.
A CancelledOrder
is conceptually distinct from an active Order
, which makes this separation intuitive for consumers.
Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder
resource.
Order
model (e.g., add cancellation-specific rules or workflows).Introduces a new resource to manage, including relationships with the original Order
(e.g., CancelledOrder
must reference the Order
it pertains to).
Consumers must now interact with multiple resources to get the full lifecycle of an order.
OrderCanceller does not sound much English. Well, it sounds made up, most nouns are. This approach represents cancellations as an action performed on an Order
, captured via a dedicated actor resource (OrderCanceller
) or a simple status update to the Order
resource.
Maintains the focus on the Order
resource, which remains central to all operations (placing, updating, canceling).
No additional resource is introduced; cancellation updates the status
field of an existing Order
object.
For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel
or PATCH /orders/{id}
.
Despite wrapping the action in a noun (OrderCanceller
), this approach may still feel action-oriented, which some might see as less ReSTful.
Order
resource.The choice hinges on whether you prioritize conceptual clarity (resource orientation) or operational simplicity (action orientation):
CancelledOrders
):OrderCanceller
):CancelledOrders
. It better encapsulates the separation of concerns, making cancellation its own first-class entity. This aligns well with resource-centric ReST design.Order
status update.Nouns don’t need to sound English, but they should align with how your domain experts and API consumers naturally think. If OrderCanceller
feels contrived, it might signal that CancelledOrders
is the more domain-appropriate model.