paint-brush
ReST: It’s More Than Just CRUD Over HTTPby@justc

ReST: It’s More Than Just CRUD Over HTTP

by JustCDecember 25th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

ReST API design isn't just CRUD over HTTP. Crafting meaningful dialogues starts with understanding user intent and business goals. For example, replacing a simple DELETE with a POST to a "CancelledOrders" endpoint can capture cancellation reasons, aiding decision-making and improving user experience.
featured image - ReST: It’s More Than Just CRUD Over HTTP
JustC HackerNoon profile picture



While CRUD provides a foundational understanding of HTTP verbs, it oversimplifies ReST API design. Many argue that ReST is just CRUD over HTTP, with:


  • POST corresponds to creation,
  • GET to retrieval,
  • PUT to updating, and
  • DELETE to deletion.


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

Step 1: Agree on the "Language" of the Conversation

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:


  • Plain text,
  • JSON,
  • XML, or
  • Even a brand-new format unique to your API.


This ensures that both parties, the user and the system, can understand each other clearly from the outset.

Step 2: Understand the User’s Intentions

Next, focus on understanding the requirements, which are essentially the user's intentions:


  • What are they trying to achieve?
  • What is the simplest, most natural way for them to express their request?

Step 3: Craft a Dialogue

Once you’ve understood the intention:


  1. Formulate a request on the user’s behalf.
  2. Craft a response that mirrors how a person would naturally reply:
    • Is the response clear and precise?
    • Does it provide all the necessary information?
    • Does it gracefully handle errors or misunderstandings?


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.”

CRUD Way

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:


  • Was there an issue with the product?
  • Was the delivery timeline too long?
  • Did the price feel too high?


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.

Intent-Based Way

POST /CancelledOrders  
Content-Type: application/json

{
  "orderId": 1234,
  "reason": "price too high"
}


A word about nouns

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.

Option 1: Resource Oriented (ex. CancelledOrders)

This approach treats cancellations as a distinct resource with its own lifecycle, attributes, and state, while keeping the original Order resource untouched.

Advantages:

  1. ReSTful Purity:
    • 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.


  2. State Representation:
    • Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource.


  3. Extensibility:
    • Provides flexibility to evolve the cancellation model independently of the Order model (e.g., add cancellation-specific rules or workflows).

Disadvantages:

  1. Complexity:
    • 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.


  2. Perceived Redundancy:
    • Since cancellation is inherently an action on an order, creating a new resource for it can feel contrived.

Option 2: Action oriented (ex. OrderCanceller)

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.

Advantages:

  1. Simplicity:
    • 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.


  2. Clarity of Action:
    • For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id}.


  3. Efficient Object Modeling:
    • Updates occur in-place without duplicating data or introducing relationships, making implementation simpler.

Disadvantages:

  1. Action Verb Leakage:
    • Despite wrapping the action in a noun (OrderCanceller), this approach may still feel action-oriented, which some might see as less ReSTful.


  2. Loss of Explicit History:
    • If cancellations are just status changes, capturing detailed cancellation metadata (reason, actor, timestamp) requires extra fields or audit logs, muddying the core Order resource.

Balancing Opinion and Rationality

The choice hinges on whether you prioritize conceptual clarity (resource orientation) or operational simplicity (action orientation):

When to Choose Resource-Oriented (CancelledOrders):

  • Cancellation has its own business significance or lifecycle beyond being an "action" (e.g., analyzing cancellations, auditing reasons).
  • You expect cancellations to have complex attributes (e.g., reasons, timestamps, or even nested workflows like approvals).
  • Aligning closely with ReSTful principles is critical for consistency across your API.

When to Choose Action-Oriented (OrderCanceller):

  • Simplicity and operational focus are higher priorities than conceptual purity.
  • Cancellation is a transient state rather than a key part of your domain model.
  • Your system and consumers are more accustomed to action-based APIs.

Concluding thoughts

  • If the reason for cancellation or its auditability is significant to your business, go with CancelledOrders. It better encapsulates the separation of concerns, making cancellation its own first-class entity. This aligns well with resource-centric ReST design.
  • If simplicity and immediacy are paramount, and cancellation is a minor detail, use the action-oriented approach with an Order status update.

Final Note:

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.