Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Hands-On Microservices with  Kotlin

You're reading from   Hands-On Microservices with Kotlin Build reactive and cloud-native microservices with Kotlin using Spring 5 and Spring Boot 2.0

Arrow left icon
Product type Paperback
Published in Jan 2018
Publisher Packt
ISBN-13 9781788471459
Length 414 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Juan Antonio Medina Iglesias Juan Antonio Medina Iglesias
Author Profile Icon Juan Antonio Medina Iglesias
Juan Antonio Medina Iglesias
Arrow right icon
View More author details
Toc

Table of Contents (14) Chapters Close

Preface 1. Understanding Microservices 2. Getting Started with Spring Boot 2.0 FREE CHAPTER 3. Creating RESTful Services 4. Creating Reactive Microservices 5. Reactive Spring Data 6. Creating Cloud-Native Microservices 7. Creating Dockers 8. Scaling Microservices 9. Testing Spring Microservices 10. Monitoring Microservices 11. Deploying Microservices 12. Best Practices 13. Other Books You May Enjoy

Domain-Driven Design

Using Domain-Driven Design (DDD) in our microservices will help us meet our microservices principles, but DDD will also help organize our products teams in ways that will benefit the value that we give from this type of architecture. But first, we need to understand what DDD actually is, and how we could apply it to create a clean architecture.

What is Domain-Driven Design

Domain-Driven Design is a software development approach to connect to an evolving complex model bounding into a core domain.

The term, Domain-Driven Design, was created by Eric Evans in his book with the same title.

When we approach a complex system, we usually abstract it to a model that describes the different selected aspects of the system, and how we could use it to solve problems. When multiple models are in play, and the code base of different models is combined, the software becomes buggy, unreliable, and difficult to understand. It is often unclear in what context a model should not be applied. The domain is the sphere of knowledge that the users of our system understand, and what they use to interact with our software; they are the domain experts.

In DDD, we define the context within which a model applies; explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas, keeping the model strictly consistent within these bounds.

Ubiquitous language

In DDD, we should build a common and rigorous language between developers and users. This language should be based on the domain model and will help us have a ubiquitous and fluid conversation with the domain experts, and will prove to be essential when approaching testing.

Since our domain model is part of our software, we should be precise to avoid any ambiguity and evolve both model and language as our knowledge as the domain grows. But when creating software, the usage of the ubiquitous language should not be only in our domain model, but also in our domain logic and even architecture. It will allow a ubiquitous understanding by any team member.

Creating tests that use the domain language help any team member to understand our domain logic.

Bounded context

When a domain model grows, it becomes complicated to have a unified domain model. Sometimes, we face a situation when we see two different representations of a concept, for example, let's examine the concept of family in a large model.

In a shopping platform, we may have the concept of products families, for example, our fabulous 32" LCD screen and the classical 24" CRT screen are part of the screen family. On the other hand, our speed offers and last day offers are part of our limited timed-offer family.

We could see that family may not be exactly the same thing on products and offers, probably they both have a unique name on their model, but in each context they may have a totally different model and logic.

In DDD, we separated them in to bounded contexts, a boundary that surrounds a model. This keeps the knowledge inside the boundary consistent, ignoring the outside world so we could still have our ubiquitous language for our domain model.

Context mapping

In a large application designed for several bounded contexts, we can lose sight of the global view. It is inevitable that the various bounded contexts will need to share or communicate data between each other. A context map is a global view of the system as a whole, showing how our bounded contexts should communicate with each other.

Context map example

This is an oversimplified example that shows three bounded contexts and how they are mapped. In the product context, we have our product and the family that it belongs to. Here, we will have all the operations for this domain context in it and it does not have a direct relation dependency to any other context.

Our offers bounded context has a dependency on the product domain context, but this is a weak relation that should purely reflect the ID of the product that a particular offer belongs to. This context will define the operations that contain the domain logic for this context.

In our shopping bound context, we have a weak relation with the product that belongs to a shopping list and will have the operations for this context. Finally, both offers and shopping concept have a relation with the customer that probably belongs to a separated bounding context.

Using DDD in microservices

Now that we have a clearer understanding of what DDD is, we need to review how we are going to apply it to our microservices. We could start with the following points:

  • Bounded Context: We should never create a microservice that includes more than one bounded context: it is better if we can map that whole context to a single microservice, something that indicates that our context is really bounded
  • Ubiquitous Language: We need to ensure that the language that our microservice speaks with is ubiquitous, so the operations and interfaces that are exposed are expressed in the context domain language
  • Context Model: The model that our microservice uses should be defined within the bounded context and use the ubiquitous language, even for entities that are not exposed in any of the interfaces that the microservices provide
  • Context Mapping: Finally, we need to review the context mapping of the whole system to understand the dependencies and coupling of our microservices

After reviewing these points, we will notice that we are in fact fulfilling the main principles defined before. Our microservices are modelled around business capabilities, our context domains, are loosely coupled as our context mapping shows, and have a single responsibility as a bound context should. Microservices that implement a bounded context could easily hide their implementation, and they will be nature isolated, so we could deploy them independently. Having those principles in place will make it easy to build for failure, having scalability and automation. Finally, having a microservice architecture that follows DDD will deliver a clean architecture that any team member could understand.


The ubiquitous language of a well-designed bounded context will make many tasks easy in a microservice life cycle, from working with the domain experts to tests or any tasks for the ops function of our team.
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at AU $24.99/month. Cancel anytime