Who owns the Orders in a consumer-provider marketplace like platform?

I’ve asked this question in StackExchange and I thought that given that the topic is related to distributed systems, I’d post it also here in case someone can help me out. Also, the solution will be implemented with NServiceBus.

tags: domain-driven design, DDD

Hi @fcastells,

let me quote here a portion of the original question

All implementations I’ve seen of similar systems contain a single Order model, which tends to be really bloated with information about the products, the provider, the consumer, invoicing, deliveries, payments, etc. I am trying to avoid that, but I am facing the question of “Who owns the order”?

  1. There is an Orders bounded context which is accessed by both the consumer and the provider. This means that the consumer api has a Place Order operation that talks to the Orders BC and creates an order and the Providers Api has an operation like Accept Order which talks to the same Orders BC and changes the status of that same order model.

  2. There are 2 Orders BCs: Consumer Orders and Provider Orders. The Consumer API places an order in the Consumer BC. This creates the order and publishes a ConsumerOrderCreatedEvent. The ProviderOrders BC listens to that event an creates a local Order (ProviderOrder) which references the ConsumerOrder. Through the Provider API the order can be accepted, which will publish a ProviderOrderAcceptedEvent, which will allow the ConsumerOrders to mark the order as accepted and notify the consumer about it.
    [/quote]

the key aspect IMO is the following (emphasis mine):

All implementations I’ve seen of similar systems contain a single Order model, which tends to be really bloated with information about the products, the provider, the consumer, invoicing, deliveries, payments, etc. I am trying to avoid that, but I am facing the question of “Who owns the order”?

The fact itself that the order is bloated with to many information, clearly owned by other services, is a sign that the first problem you need to look at is the Order model. It’s probably too big, with too many responsibilities.

From the logical point of view we can probably identify an Order owner, let’s say that it’s called Sales.

Now as you state in your scenario there is the need to identify one or more providers, that will accept and fulfill the Order, does Sales own the providers information? probably the answer is no. A Provider Registry service is a better fit.

Same reasoning applies for customers information on the order, Sales doesn’t own any customer information, a Customer Registry service owns those information.

Same goes for all other information you mentioned above. We could probably go as far to saying there won’t be any product information on the order itself, Warehouse owns products information, not the order.

So which data will we put into the Order? IDs, just IDs. The Order will contain the customer ID and provider(s) ID(s), Products IDs, Shipping Information IDs, etc.
ViewModel Composition techniques will be applied so that when displaying the order it’ll appear like information are all stored in the same place, even if that’s not the case.

You can read more about ViewModel composition here: https://particular.net/blog/secret-of-better-ui-composition
There is a full working sample available in the SOA Done right workshop repo.

.m

All this makes perfect sense in terms of information linked to an order.
My next question then is about the “orders workflow”. An order will transition from Placed, to accepted or rejected. It can also be cancelled by the consumer or by the provider under some conditions. Its delivery can start and end (delivered).
The order workflow will be triggered by commands coming from the Consumer, Provider and Backoffice (customer service) APIs. I have the feeling (not a certainty yet), that an order will have more states from the Provider point of view than from the Consumer, as the provider will need to “work on the order”, whether the consumer only needs to know that the order is on its way without too much more detail.

My question is: do all these commands go to a single Sales BC, where there is a single representation of a given order (maybe a Saga) which transitions from one state to another? or would there be an order (simple) on the consumer side and an order (more complex) on the provider side which are coordinated by events?

My reasons for thinking that the consumer and the provider orders are separate are:

  1. Potentially a single Consumer order can become several Provider orders (for an order for multiple providers).
  2. The Provider order’s workflow can be more complex and it might contain information that should always be hidden to the consumer, like internal order handling operations and who did them.
  3. Also, I imagine the scenario where the consumer application and the provider application were developed by 2 different companies. They would develop their own order BC and integrate with each other through some sort of interface. Obviously this point is a complexity that we don’t really have, but we do have 2 separate teams that independently develop the Consumer and the Provider features.

you just described 2 sagas:

  1. Order Saga
  2. Shipping Saga

Placed, Accepted, Rejected, or Cancelled are all handled by the Order saga. As soon as the order is ready (that’s probably another status) it cannot be anymore cancelled thus the order saga is “frozen” and the ready event kicks off the shipping saga.
A similar reasoning can be applied to the payment, if payment is by credit card only then probably Finance is just a service that talks to credit card providers, but if wire transfers are accepted, the payment quickly becomes another saga and you don’t want to bloat the order management saga with payment processing details.

Again ViewModel composition techniques can be applied to display to users, providers and back-end operators the overall status of an order.

OK. It makes sense (I already modeled the shipping separately from the order, but we still have a Delivery status in the order).
I will think about all this and check the links you sent before.

Many thanks

Having a delivery status in the order saga might be tricky.

Think for example to electronic deliveries, e.g. a provider sells mp3, there is no delivery concept. Or much worse multiple providers shipping things at different times, or a single provider shipping a single order with multiple items with more than one delivery (Amazon can do this for example).

Having a single delivery status in the order saga might complicate things without gaining any real advantage.

.m

Yes, I know. I created the separated the delivery concept, but the “delivered” status is still in the order. It’ll be gone soon, I hope. But there’s a lot to do.