Rest – Partitioning REST API resources into areas based on business domains

api-designArchitecturerest

In a major application REST API that covers several related domains, does it make more sense to split resources into 'areas' based on the business domain they belong to or is it better to to maintain a single model?

For example, there are 'Sales' and 'Inventory' sub-domains. Users of the system typically only care about one domain at a time, but exceptions are possible.
There is an 'Item' concept that exists in both domains so we could implement the 'item' resource in two different ways.

  1. have different resources to represent the concept in each domain, each resource holding only the relevant data:

    /sales/items/:id

    /inventory/items/:id

  2. have a single resource with all the data to be used in all contexts:

    /items/:id

There are also plenty of resources that only belong to one of the domains.

pros of 'areas'

  • easier to understand the API for users who only care about a single domain
  • easier to implement resources (less stuff to read/update at a time)
  • resources can be more specialized/optimized for each particular domain
  • ability to control access to resources at more granular level

pros of a single unified model

  • no duplicated resources for concepts that belong to more than one domain
  • if a user needs to work with multiple domains, he will only have to use a single API that covers all his needs

Is API partitioning as described above a valid way to reduce complexity of both API contract and implementation? I haven't seen it mentioned much anywhere.

Are there any more things that need to be considered to make a decision in favor of either approach?

Best Answer

I think that this is the perfect fit for Bounded Context pattern from Domain Driven Design.

Large models don't scale well, it's better to split them into smaller models (bounded contexts) and explicitly declare their relationships (common entities, interactions between bounded contexts etc.)

In this case you would have two bounded contexts (sales and inventory) with one shared resource (item). Interpretation of item in sales context may be a bit different than in inventory context and that's completely fine.

To use this pattern, you should:

  • identify the boundaries of different contexts (which you partly did by creating subroots /sales/ and /inventory/)
  • identify shared resources (item) and explicitly describe what is resource's interpretation in different bounded contexts
  • identify interactions between bounded contexts (which is probably out of scope of this question)

Note on

pros of a single unified model: no duplicated resources for concepts that belong to more than one domain

From REST point of view, resource is not duplicated. One resource can be identified by multiple URIs, each can have different representations (fitting for given bounded context).