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: Formulate a request on the user’s behalf. 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: 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. State Representation: Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource. Extensibility: Provides flexibility to evolve the cancellation model independently of the Order model (e.g., add cancellation-specific rules or workflows). Disadvantages: 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. 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: 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. Clarity of Action: For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id}. Efficient Object Modeling: Updates occur in-place without duplicating data or introducing relationships, making implementation simpler. Disadvantages: 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. 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. 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. POST corresponds to creation, POST GET to retrieval, GET PUT to updating, and PUT DELETE to deletion. DELETE 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: first episode ReST API design is like scripting a dialogue between two people ReST API design is like scripting a dialogue between two people Step 1: Agree on the "Language" of the Conversation 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. 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 Step 2: Understand the User’s Intentions Next, focus on understanding the requirements , which are essentially the user's intentions: requirements What are they trying to achieve? What is the simplest, most natural way for them to express their request? What are they trying to achieve? What are they trying to achieve? What is the simplest, most natural way for them to express their request? What is the simplest, most natural way for them to express their request? Step 3: Craft a Dialogue Step 3: Craft a Dialogue Once you’ve understood the intention: Formulate a request on the user’s behalf. 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? Formulate a request on the user’s behalf. request 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? response Is the response clear and precise? Does it provide all the necessary information? Does it gracefully handle errors or misunderstandings? 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. example DELETE While technically valid, this design overlooks a critical aspect: understanding the “why.” understanding the “why.” CRUD Way CRUD Way CRUD Way DELETE /orders/1234 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: DELETE Was there an issue with the product? Was the delivery timeline too long? Did the price feel too high? 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. POST Intent-Based Way Intent-Based Way Intent-Based Way POST /CancelledOrders Content-Type: application/json { "orderId": 1234, "reason": "price too high" } POST /CancelledOrders Content-Type: application/json { "orderId": 1234, "reason": "price too high" } A word about nouns 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. CancelledOrders CancelledOrders OrderCanceller, OrderCanceller, Let’s look at these two nouns systematically, balancing opinions and rationale. Option 1: Resource Oriented (ex. CancelledOrders) 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. Order Advantages: Advantages: 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. State Representation: Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource. Extensibility: Provides flexibility to evolve the cancellation model independently of the Order model (e.g., add cancellation-specific rules or workflows). 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. 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. Emphasizes nouns/resources over actions, aligning with ReST's guideline of avoiding verbs in URIs. 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. A CancelledOrder is conceptually distinct from an active Order , which makes this separation intuitive for consumers. CancelledOrder Order State Representation : Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource. State Representation Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource. Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource. Captures the cancellation reason and metadata (timestamp, actor, etc.) naturally as attributes of the CancelledOrder resource. CancelledOrder Extensibility : Provides flexibility to evolve the cancellation model independently of the Order model (e.g., add cancellation-specific rules or workflows). Extensibility Provides flexibility to evolve the cancellation model independently of the Order model (e.g., add cancellation-specific rules or workflows). Provides flexibility to evolve the cancellation model independently of the Order model (e.g., add cancellation-specific rules or workflows). Order Disadvantages: Disadvantages: 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. Perceived Redundancy: Since cancellation is inherently an action on an order, creating a new resource for it can feel contrived. 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. 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. Introduces a new resource to manage, including relationships with the original Order (e.g., CancelledOrder must reference the Order it pertains to). Introduces a new resource to manage, including relationships with the original Order (e.g., CancelledOrder must reference the Order it pertains to). Order CancelledOrder Order Consumers must now interact with multiple resources to get the full lifecycle of an order. Consumers must now interact with multiple resources to get the full lifecycle of an order. Perceived Redundancy : Since cancellation is inherently an action on an order, creating a new resource for it can feel contrived. Perceived Redundancy Since cancellation is inherently an action on an order, creating a new resource for it can feel contrived. Since cancellation is inherently an action on an order, creating a new resource for it can feel contrived. Option 2: Action oriented (ex. OrderCanceller) 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. Order actor actor OrderCanceller Order Advantages: Advantages: 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. Clarity of Action: For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id}. Efficient Object Modeling: Updates occur in-place without duplicating data or introducing relationships, making implementation simpler. 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. 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. Maintains the focus on the Order resource, which remains central to all operations (placing, updating, canceling). Maintains the focus on the Order resource, which remains central to all operations (placing, updating, canceling). Order No additional resource is introduced; cancellation updates the status field of an existing Order object. No additional resource is introduced; cancellation updates the status field of an existing Order object. status Order Clarity of Action : For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id}. Clarity of Action For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id}. For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id}. For consumers, "cancelling an order" as an action maps naturally to POST /orders/{id}/cancel or PATCH /orders/{id} . POST /orders/{id}/cancel PATCH /orders/{id} Efficient Object Modeling : Updates occur in-place without duplicating data or introducing relationships, making implementation simpler. Efficient Object Modeling Updates occur in-place without duplicating data or introducing relationships, making implementation simpler. Updates occur in-place without duplicating data or introducing relationships, making implementation simpler. Disadvantages: Disadvantages: 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. 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. 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. 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. Despite wrapping the action in a noun (OrderCanceller), this approach may still feel action-oriented, which some might see as less ReSTful. Despite wrapping the action in a noun ( OrderCanceller ), this approach may still feel action-oriented, which some might see as less ReSTful. OrderCanceller 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. 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. If cancellations are just status changes, capturing detailed cancellation metadata (reason, actor, timestamp) requires extra fields or audit logs, muddying the core Order resource. Order Balancing Opinion and Rationality 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 ): 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. 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 ): 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. 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 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. 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. reason for cancellation go with CancelledOrders If simplicity and immediacy are paramount, and cancellation is a minor detail, use the action-oriented approach with an Order status update. action-oriented approach with an Order Final Note: 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. OrderCanceller CancelledOrders