Domain-Driven Design for Microservices

What is Domain-Driven Design?

Domain-Driven Design (DDD) is a software design method wherein developers construct models to understand the business requirements of a domain. These models serve as the conceptual foundation for developing software.

Bounded Context (BC)

The setting in which a word appears determines its meaning. Depending on the context, “book” may refer to a written piece of work, or it may mean “to reserve a room”. A bounded context (BC) is the space in which a term has a definite and unambiguous meaning.

Context Map

The presence of a BC anticipates the need for communication channels. For instance, if we’re working in an e-commerce domain, the salesperson should check with inventory before selling a product. And once it’s sold, it’s up to shipping to ensure delivery of the product to the correct address. In DDD, these relationships are depicted in the form of a context map.

Domain-Driven Design for microservices

DDD takes place in two phases:

  1. In the strategic phase we identify the BCs and map them out in a context map.
  2. In the tactical phase we model each BC according to the business rules of the subdomain.

Strategic phase

During this phase, we invite developers, domain experts, product owners, and business analysts to brainstorm, share knowledge and make an initial plan. With the aid of a facilitator, this can take the form of an Event Storming workshop session, where we build models and identify business requirements starting from significant events in the domain.

  • Open Host Service (OHS): the service provider defines an open protocol for others to consume. This is an open-ended relationship, as it is up to the consumers to conform to the protocol.
  • Published Language (PL): this relationship uses a well-known language such as XML, JSON, GraphQL, or any other fit for the domain. This type of relationship can be combined with OHS.
  • Anticorruption Layer (ACL): this is a defensive mechanism for service consumers. The anti-corruption layer is an abstraction and translation wrapping layer implemented in front of a downstream service. When something changes upstream, the consumer service only needs to update the ACL.
  • Separate ways: this happens when integration between two services is found, upon further analysis, to be of little value. This is the opposite of a relationship — it means that the BCs have no connection and do not need to interact.

Tactical phase

Deep down, software development is a modeling exercise; we describe a real-life scenario as a model and then solve it with code. In the previous stage, we identified BCs and mapped their relationships. In this stage, which requires developers well-versed in DDD theory, we’ll zoom in on each context to construct a detailed model.

  • Entities: entities are objects with an identity that persists over time. Entities must have a unique identifier (for example, the account number for a customer). While entity identifiers may be shared among context boundaries, the entities themselves don’t need to be identical across every BC. Each context is allowed to have a private version of a given entity.
  • Value objects: value objects are immutable values without identity. They represent the primitives of your model, such as dates, times, coordinates, or currencies.
  • Aggregates: aggregates create relationships between entities and value objects. They represent a group of objects that can be treated as a single unit and are always in a consistent state. For example, customers place orders and own books, so the entities customer, order, and book can be treated as an aggregate. Aggregates must always be referenced by a main entity, called the root entity.
  • Domain services: these are stateless services that implement a piece of business logic or functionality. A domain service can span multiple entities.
  • Domain events: essential for microservice design, domain events notify other services when something happens. For instance, when a customer buys a book, a payment is rejected, or that a user has logged in. Microservices can simultaneously produce and consume events from the network.
  • Repositories: repositories are persistent containers for aggregates, typically taking the form of a database.
  • Factories: factories are responsible for creating new aggregates.

Domain-Driven Design is iterative

While it may appear that we must first write an exhaustive description of the domain before we can begin working on the code, the reality is that DDD, like all software design, is an iterative process.

More ways of designing microservices

DDD is undoubtedly a theory-heavy design pattern. As a result, it is only recommended when the system under development is complex enough to warrant the extra planning work.

  1. Identify microservices and their relationships with strategic DDD.
  2. Model each microservice with tactical DDD.
  3. Since each team is autonomous, they can choose to adopt BDD or TDD (or a mix of both) for developing a microservice or a cluster of microservices.

Learn more about Domain-Driven Design

DDD can feel dauting to learn and implement, but its value for developing a microservice architecture is well worth the effort. If you found the information in this article interesting, I recommend picking up the relevant books by Eric Evans and Vaughn Vernon to learn more.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Semaphore

Semaphore

Supporting developers with insights and tutorials on delivering good software. · https://semaphoreci.com