Which Capabilities Share a Service

The second decision is which capabilities share a service. Capabilities that use the same data and change for the same reasons go in one service.

Between services, we want loose coupling: each service can change inside without forcing a change to the others, as long as the calls between them stay the same.

The catalog, carts, and orders

Placing an order reads the cart, reduces the stock of each product in it, and records the order, all in one transaction. Because we shard by shop, the cart, the products, and the order are on the same shard, so the transaction stays on one database server.

Suppose the catalog, the carts, and the orders were three services. Services may share a database, so the three could keep their data where it is now. But then the order service would reduce the stock and close the cart by writing directly to data that belongs to the other two services. A change to how the catalog stores products, or how the carts store items, would force a change to the order service. The three would be tightly coupled. And if each service kept its data apart from the others, we could not place an order in one transaction.

So I keep the catalog, the carts, and the orders in one service, the commerce service. They use the same data, and placing an order needs all three at once. I put taxes with the orders, because they are part of an order’s total.

The other capabilities

  • Opening shops and managing accounts. When a merchant signs up, we create the merchant’s account and the shop together. A shopper’s account belongs to one shop. Both change for the same reasons, such as a new step in signing up or a new way to sign in. I put them in one service, the account service.
  • Taking payments. Adding a new way to pay, such as Apple Pay, changes how payments are taken and does not change the orders. Most businesses do not build this themselves. They use a payment processor, a company such as Stripe or PayPal that takes card payments for other businesses. I put payments and refunds in one service, the payment service. The payment service works with the payment processor.
  • Shipping orders. Shipping works with the carriers that deliver the parcels. A shipment starts after the order is placed and takes days. I give it its own service, the shipping service.
  • Notifying shoppers. The wording and the look of the emails change often, and none of those changes touch the orders. I give it its own service, the notification service.

The commerce service calls each of the last three for one or two things: take a payment, ship an order, send an email. Those calls are all the commerce service needs from them, so all three are loosely coupled to it.

Shopend now has five services: the commerce service, the account service, the payment service, the shipping service, and the notification service.

One database

The five services share one database, as the registrar’s application and API do. Each service reads the data it needs directly. For example, to send an email, the notification service reads the shopper’s email address from the accounts.

Sharing the data has a cost. If the account service changes how it stores accounts, the notification service has to change too. With five services, I accept that cost. Only a few services read data that another service writes, so a change like this is easy to coordinate.