Book notes – Microservice patterns: with examples in java

You can buy this book from

This book explains how to refactor monolithic applications into microservices and provides you arguments, when it is needed.

Hexagonal architecture, which is described in Chapter 1 can be a basis for microservices. In this type of architecture, functionality (business logic) is in center of implementation. Inbound and outbound data flow is implemented as adapters, which can be easily replaceable. During discussion of salability, scale cube in Chapter 1 is introduced. This cube consists of the following dimensions:

  • scale by cloning
  • scale by splitting similar things, such as by CustomerId
  • scale by splitting things, that are different, such as by function.

Comparison of microservices and SOA shows, that in microservices dumb pipes (for example Kafka) in comparison to SOA (AMQP) are used. Moreover, direct communication is done using REST or gRPC, in comparison to old SOAP/WS stack. For microservices local database per microservices is common choice. Integration using database should be avoided. For SOA, large global shared database is standard.

During development separation between Command (create, update, and delete of data) and Query (read of data) functionality should be applied (CQRS pattern). That means database for operational purposes should be separated from analytical database.

There are two decomposition strategies:

  • decompose by business capability (Supplier management, Consumer management, Order taking and fulfillment, …)
  • decompose by subdomain (Order taking subdomain, Accounting subdomain, Delivery subdomain, …).

Warning: avoid distributed monolith!

Warning: avoid God classes, which are used in different services. Solution is to create copy of the same class, which contains only microservice relevant attributes.

Some words about shared libraries between microservices. From one side you should use DRY (do not repeat yourself) principle, another side, dependency between services are introduced, so it is not possible to deploy them independently. Shared libraries are good for functionality, which is changed very rarely. You should also think to create one more service instead of shared library.

Sagas as a pattern for distributed transactions can be used. Event sourcing can play important role here. Event sourcing is when initial state of object and consequently all changes of this object are stored. To reconstruct state of the object at current point of time, it is needed to retrieve initial state and apply all changes to it. Event sourcing can help to implement distributed transactions with sagas, since it is easy to define compensation transactions in case of rollback.

Microservices should be independently deployable, to improve development velocity.

I have found interesting discussion in Chapter 12 about serverless/containers/virtual machines/bare metal deployment models. Interesting idea is to check first, if application can be implemented with serverless model, and only after that consider containerization.