Colored Services

Defining service boundaries is hard. Let's bring some colors and make it fun!

Trying to define services first and partition their functionality later is often a misleading approach ending up in the Entity Services antipattern. One can't really know what the right boundary is up-front, it is a process of discovery. Better is to group use-cases that belong together, the services will emerge by themselves. Purely for differentiation we can use colors, numbers or vegetable. Don't try to find right names until the process is finished and every use-case has its home.

I’ve heard about this technique for the first time from Udi Dahan, but unfortunately it seems no paper is to be found on the topic. This is my humble attempt.

First, let's define the requirements.

Now, we can analyze those and scratch the first services.

That's pretty obvious. The service needs to have the product title, description and price.

In order to provide this, a list of categories must be shown first:

For categories, we probably want some nice looking URIs in our e-shop like /toys or /books. The URI will be used for searching. As we neither want to have URI duplicated in products nor to do two hops to get the Category ID first, we put the List categories use-case into the same service as both Find products use-cases. Let's call it “Blue“:

Blue service

Next is the product availability. We want to show how many is left in stock. This information is not necessary for sale. A customer can order a product even when there are no items left in stock. This can just delay delivery or, alternatively, another product can be offered. No items in stock must not prevent the customer from placing an order - this is a business decision. This means we can model the stock information in a separate service, let's call it “Green“:

Green service

There are two important rules for the shopping cart. First says that a product can be added multiple times. This means we need to hold a quantity with each cart item. Second say that the product in cart must not change. This means the cart items are kinda snapshots of the products at the time of adding. That's why putting the cart functionality into the blue service wouldn't be the best idea: we need a new representation of product - a cart item. Besides, cart items are fully independent on products and categories. Let’s put it into a new “Red” service:

Red service

Order items have similar rules like cart items, both are immutable snapshots of products at some particular time, except we don't need all information about the product in the order. The life cycle differs: while cart items can be added and removed, the order is typically immutable. The order total amount is not only sum of item prices but can include additions like shipping fees, taxes, discounts etc. That's why we need to model the total amount separately. As we agreed the order didn't belong to the same service as shopping cart, we have to put it into a new service, called “Yellow“:

Yellow service

Although the customer fills up shipping information as a part of the order process, the order process is fully independent on it. An order can be placed even without shipping information - consider an online delivery of an e-book etc. We put it into a new service, let's call it “Violet“:

Violet service

Similar with payment. Here the amount to pay is needed, because the payment doesn't necessarily have to be for the order as whole. Finishing the order process can contain several other payments like additional fees or discounts. A payment is not necessarily connected to an order as it could be used for different purposes like loyalty program, membership fees etc later. Let's call the new service “Orange“:

Orange service

Fetching goods should have an obvious impact: the amount in stock decreases. We put this use-case into the Green service:

Green service

When all the use-cases are partitioned into services, it’s pretty straightforward to give them appropriate names.

Colored services

You can see this idea in action on my GitHub.

Happy coloring!