Stop Forcing REST onto Domain-Driven Architectures
Many teams struggle applying REST in domain-driven systems, often leading to complexity. Discover why RPC-style APIs are a better fit for these architectures.
Understanding REST vs. Domain-Driven Design Conflicts
For years, I've seen teams struggle to mesh REST principles with domain-driven architectures. Initially, they establish clean REST endpoints. However, as business requirements evolve, these designs get compromised. Eventually, most REST principles are dropped as complexity soars. This pattern isn't accidental; it's due to a fundamental clash between REST's assumptions and domain-driven design's realities.
Why Doesn't REST Mesh Well with Domain-Driven Design?
REST focuses on resource-centric views, assuming globally consistent entities. In contrast, domain-driven design (DDD) centers on bounded contexts and business capabilities, challenging REST's global resource navigation.
For instance, in DDD:
- A
Userin the Orders context might have{id, shippingAddress}. - The same user in the Identity context could be
{id, email, preferences}.
This variance complicates RESTful API implementation. If the Orders service needs customer info, who owns the user representation? It can't be the Orders service, as user data falls under the Identity service.
How Do Teams End Up Compromising REST Principles?
Faced with these challenges, teams often dilute REST principles to keep REST-like endpoints, leading to complex solutions like:
- Adding context prefixes:
/orders/api/users/{userId}/orders - Using domain-specific naming:
/orders/customers/{customerId}/orders - Treating cross-context queries as searches:
/orders/search?customerId={id}
Some opt for gateway routing, which maps clean URLs to internal paths, e.g., /users/{id}/orders to /orders-service/customers/{id}/orders. This, however, can introduce fragile configurations and expose incorrect user models to clients.
Why Does REST Struggle with Complex Business Operations?
REST shines with operations that neatly fit CRUD actions. But complex business tasks, like "partially canceling an order for specific items," don't align well. Teams try to fit these into REST by:
- Misusing
PATCH /orders/{id}/line-itemswith unclear request bodies. - Employing
POST /orders/{id}/partial-cancel, which veers off REST norms. - Creating artificial resources that reflect workflows, not real entities.
These approaches deviate from REST's core principles, obscuring operations or pretending they're resource-based.
When Is REST Most Effective?
Despite its limitations, REST has benefits in certain scenarios:
- Caching: Reduces server load through HTTP caching.
- Hypermedia: Allows clients to dynamically discover capabilities.
- Uniform interface: Facilitates the use of generic tools across APIs.
Yet, domain-driven systems seldom gain from these advantages. For example, caching /orders/12345 doesn't account for business events like cancellations or shipments, making cached data quickly obsolete.
Many REST implementations stem from tutorials focused on HTTP, JSON, and resource URLs, missing the architectural depth that gives REST its strength. This often leads to HTTP-based RPC that mimics REST without harnessing its full potential.
Why Are RPC-Style APIs More Suited to Domain-Driven Design?
RPC-style APIs align API design with business operations through explicit, verb-based endpoints like /orders/cancel, /orders/refund, and /orders/split-shipment. This removes the need to translate domain operations into API structures.
RPC endpoints also simplify documentation. Compare POST /orders/cancel with PUT /orders/{id}, where the latter could mean updating status, adding items, or changing shipping details based on the request body. The generic update endpoint complicates client interactions with a uniform interface.
Conclusion: Choosing the Right Architecture
REST suits entity-driven systems with consistent global resources, perfect for CRUD operations like media libraries or inventory systems. However, for domain-driven systems with bounded contexts and complex operations, RPC-style APIs are a better fit.
To improve your system design:
- Adopt explicit, verb-based endpoints mirroring business capabilities.
- Avoid cramming operations into resource updates.
- Recognize that different bounded contexts need unique resource definitions.
Understanding REST's limitations in domain-driven designs enables developers to craft clearer, more effective, and purpose-aligned APIs.
Related Articles

Mastering MCP Elicitation for Enhanced AI Interactions
Discover the power of MCP elicitation in creating seamless AI interactions, from streamlining development to improving user satisfaction.
Sep 10, 2025

Exploring Kotlin Beyond Android: A Multiplatform Powerhouse
Kotlin transcends its Android roots, emerging as a multiplatform powerhouse. Explore its capabilities beyond mobile development.
Sep 9, 2025

Rethinking Network Security with Physics Principles
Discover how viewing networks as energy systems, with data flows and security mechanisms akin to electricity and circuits, can revolutionize cloud security.
Sep 7, 2025
Comments
Loading comments...
