Because we are at the beginning of our journey into microservices and a true service-based architecture, we can start on the right foot by properly organizing them so they can be shared, found and reused. After all, if our services are not being reused, what is the point? Let’s not make the same mistakes we made during the days of object-oriented programming (yes, OOPs). While OOPs was great in theory, we had issues with implementation—developers struggled to create an organizational structure that was built into software builds at link time, causing OOPs to turn into lots of copied libraries, sometimes with the same name. And then yes, we renamed them. What an unfortunate missed opportunity. If we take the same approach to microservices, we will repeat the same mistake.
I know: No one wants to file things or put them in the proper place. But if we are to succeed in a service-based architecture, we must keep the ship tidy. This is the purpose of a domain-driven design for creating and cataloging microservices.
Domain-driven design (DDD) is a method of software development that must be applied to the organization of microservices. Using a domain-driven design makes it easier for developers to categorize—and subsequently find—microservices that can be shared across teams. Key to a domain-driven design is defining a hierarchical structure that allows the high-level domains to be shared down to the child sub-domains. For example, your infrastructure and data access services should be shared from the highest-level domain down to all development teams. However, security and organizational structure may require the “fraud detection” services to be shared to the “online banking” services, but not vice versa.
Domain-driven design structure can be used to:
- Group “like” microservices together as a package.
- Organize, with sub-domains, based on a “business” or “problem” space.
- Encourage reuse and collaboration.
- Track a service version to an software application version, providing a single source of truth.
Breaking Down Domains
When defining your domains, think of a model as follows:
|Global Domain||This is the highest-level of your domain-driven design structure. Any microservice defined to the global domain is shared to all lower-level domains.|
|Division Domain||Division domains are used to define an organizational structure that closely represents how you do business, such as geographical areas, problem sets, organizational responsibility or business units. A division domain is a folder of other subdivision domains and project domains. Division domains adds flexibility to how you define your domain-driven design. Division domain inherits microservices in the global domain.|
|Project Domains||Project domains contain microservices that are reusable only to the project and are only shared across a single project team.|
And when defining your domains, rely on an old computer science mantra: KISS. The goal is to simplify, not to make more complex. We are talking about creating a structure that makes things easy to find, not obfuscate (which some DDD models tend to do).
The most difficult process will be decomposing your organizational software and defining your division domains. Once these are clearly outlined, the rest becomes easy. Division domains could include:
- User Management.
- Log Management.
- Social Networking.
- Bots/Machine Learning.
- Common – An airline might have a collection of services that report schedules that other project teams might use; a bank teller division domain may have project subdomains that include accounts, statements, customer details and reconcile logic.
Domain-driven design allows you to define categories of microservices and to whom they can be shared. In this way, you can classify your microservices into “problem spaces,” organizational structures, geographical areas or lines of business. Domains create a “catalog” of shareable microservices that allows development teams to easily publish and/or reuse microservices across your organization.
Lots of Information to Share
Let’s face it, implementing microservices could become a huge tangled hairball without a domain-driven design. We know from our experience around object-oriented programming that sharing and collaborating around the use of services will become critical for their success. We know we’re failing when each team begins to “copy” and “rename” their own versions of services. This would be bad. A domain-driven design provides a collaboration framework so that your service can be published and shared across teams. This allows them to choose a service from a component list. Providing a central repository of the available services also reduces the temptation of taking an older version of a service and making it “our own.” Domain-driven design is easiest to follow when you have a central tool to organize and share the microservices. DeployHub does this through organizing, packaging and versioning your services before the deployment.
Getting it Done
Start by defining your Domains on paper first. As you begin to decompose your monolithic applications into services, you will need to look for patterns. These patterns will become your Domain Design. Using a versioning tool such as GitHub will allow you some help with organization and version tracking, as well as collaboration. Using an open source tool such as DeployHub will allow you to catalog under a domain structure prior to deployment keeping track of who is using the services and providing a logical representation of your monolithic equivalent. After all, what we are creating is a “single source of truth” about microservice, their availability, relationships and usage. More on that in another blog.
Domain-Driven Design: Further Reading
“Decompose by Sub-Domain – Microservices.io,” by Chris Richardson