Microservices Patterns notes
I am not done with this excellent book yet, but I decided to go ahead and publish this in case it may help anyone else. If you are trying to decide on a book to buy about Microservices, this is the book I suggest after much research. You will open this book many times when designing your systems, it is that full of good information.
Microservices Patterns is an Excellent book by Chris Richardson. This book contains so much useful information, mine has started to look like a coloring book with all of the underlining notes and highlighting. These are my notes for myself so I can re-find useful information later. Since I have several books on the subject and pages of links, it helps to be able to remember where I found what. Actually this entire site started as a way to document the things I learn about Microservices and software engineering, hence all the resource pages and long lists of resources.
I’ve been studying modular software design and microservices in particular for about 2 years. So far this book is the most useful and informative yet. So much of it reaffirms things I have either thought or read about, this book really helps to clarify the topics and assure me that I am correctly understanding things.
Chapter 1 Escaping Monolithic Hell
Chapter 1 “Escaping Monolithic Hell” is about exactly what it sounds like. It starts out by discussing the horrible realities of monoliths, it also discusses the drawbacks of the Microservice architecture. Monolithic hell and all of it’s problems is what lead me to researching modular software design and ultimately microservices. It only takes one good kick in the balls by monoliths to make you never want to ever build one ever again no matter what you do. This chapter discusses software and architectural patterns, pattern languages and why they are important. This first chapter is a great introduction to the subject of Microservices vs Monoliths.
Chapter 2 goes into details about how to break a monolithic app into microservices. This is one of the most direct explanations I have seen so far. Chris starts out by defining exactly what a Microservice is. It took me a while to finally get to this single answer, so many other sources are wrong or indirect. He discusses how not to create a Microlith or distributed Monolith through loose coupling of services ~page 42 What is loose coupling?
Chapter 2 Domain Decomposition Strategies
Chapter 2 is very helpful with the discussion on how to find your apps Microservices. This is one of the most helpful discussions I have found on the subject. It starts out by discussing software architectural styles to help you get an understanding of the many ways of doing things. Around page 44 the discussion on Microservice architecture begins with a discussion on how to find the system operations beginning at 2.2.1 bottom of page 45. The next few pages are very handy with their discussion on how to create the domain model from requirements. This chapter discusses breaking down the Domain by Business capabilities and by the DDD approach of Decompose by sub-domain pattern, both end up in the basic same results as Chris points out.
- Page 48 – 49 “Defining System Operations” – discusses identifying the system commands for CQRS
- Page 51-53 -” Defining services by applying the Decompose by Business capability pattern”
- Page 54 – 2.2.3 “Defining services by applying the Decompose by sub-domain pattern”
- page 56 “Decomposition guidelines” Very handy information here, Single Responsibility principle and Common Closure principle.
- Page 57 – 60 – “Obstacles to decomposing an application into services”. Very useful information here about the many problems you will face
- Page 61- 62 – “Defining Service API’s” discusses how to define your service api’s and what is involved
- Page 62 – “Determining The API’S required to support collaboration between services” Very important section here to help start understanding some of the things you will need to know to properly build a service api
Chapter 3 Interprocess communication in a microservice architecture
Communication between Microservices is actually one of the hardest things about building a system with microservices. Get it wrong and your app just doesn’t work and you’ve built a big valueless mess. This is a huge chapter starting on page 65 and ending on page 107. This chapter covers pretty much all you need to know about current interprocess communication in microservices. So many things are summed up right here in one chapter, things I had to dig and dig to find slowly, some sources were better than others.
Starting on page 68 the author discusses how to define an API, page 69 leads into evolving an API
- Page 68 3.1.2 discusses how to define an API
- page 69 3.1.2 Evolving an API discusses the need for API versioning
- page 70 discusses Semantic Versioning and how it works
- Page 71-72 3.1.4 Message formats useful information binary vs text
- Page 72 Remote Procedure Invocation – about the same as RPC more info at this link
- Page 73 – 76 3.2.1 discusses using REST for RPI it covers the pro’s and con’s This is a very clear explanation of how the entire process works. This is an excellent explanation of REST, it’s concepts, how it works etc. Chris mentions the Rest Maturity Model, the first I have heard of this. Here is a link REST Maturity Model. HATEOAS discussed page 74. Interesting article about HATEOAS and why you should use it if you are doing REST
- page 74 “Specifying REST API’s mentions using the Open API Specification for building your API it also mentions Swagger started trend this off.
- Page 75 mentions using GraphQL or Netflix Falcor to enable complex REST queries.
- Page 75 also mentions the pros and cons of using REST
- Page 76 starts a discussion of gRPC
- page 77 gives the pros and cons of gRPC
- page 77 – 3.2.3 bottom of page talks about handling partial failure using the circuit breaker pattern more on the circuit breaker pattern here a good pattern to use in your Ajax requests too
- page 79 Developing robust RPI Proxies discusses fault tolerance with RPI so it doesn’t RIP it mentions using Netflix Hystrix to solve problems.
- page 80 3.2.4 Using Service Discovery – starts the discussion about service discovery, what it is and why you need it.
- page 81 mentions Service Discovery patterns one being the Self Registration pattern
- page 82 mentions the Client-side discovery pattern
- page 83 Applying The platform-provided service discovery patterns – This section talks about using Docker and Kubernetes for service discovery. The main benefit to platform-provided service discovery is that the platform takes care of everything and it is language independent.
- page 85 has links to 3rd Party Registration Pattern, Server Side Discovery Pattern and Messaging Pattern
- Page 85 3.3 Communicating using the Asynchronous Messaging Pattern begins.
- Page 86 covers the types of messages document, command and event it also mentions the message channel described in this link
- Page 87 describes two types of messaging channels point to point which ensures only one service receives the message, this is used for service to service communication commands in CQRS systems are usually sent by point to point messaging and publish-subscribe channel which allows one service to send a message and more than one service can receive and act upon it. Services usually emit events as a publish-subscribe pattern so that more than one other service can act upon the message.
- Page 87 3.3.2 Implementing the interaction styles using messaging Begins the discussion on interaction styles for message based interactions.
- Page 88 has a great description of how the entire messaging process works between Services with a nice diagram
- Page 89 “Implementing Publish/Subscribe” – gives an excellent description of how one-to-many event broadcasting works for one service to emit an event that multiple other services can consume.
- Page 89 Implementing publish/async responses This section explains how publish/subscribe works with asynchronous responses. A message gets published to the Message Queue/broker, an interested service reads the message and responds. All interactions are tracked/happen with correlation id’s
- Page 89 3.3.3 Creating an API Specification for a messaging-based service API – this section starts to explain how to design the API’s for your services.
- Page 90 3.3.4 Using a message broker – starts the description of using message brokers for the message communication pattern.
- Page 91 Brokerless messaging – this section quickly covers a messaging pattern that does not use a message queue or broker. This is something I would use for the right project when I find it.There is software for this ZeroMQ I read an article where someone used this and had to redesign the system to use a broker. Each system is different, that is why software exists for this situation. You should do hundreds of hours of research to decide what is right for you or read Chris Richardson’s’ book.
- Page 92 Overview of Broker-Based messaging – Section lists several message queue/brokers and mentions a few important things to look for. This is a very helpful section.
- Page 93 “Implementing message channels using message brokers” – this section has useful information about how different brokers handle messaging. This helps you decide which broker to use for which situation.
- Page 93 “Benefits and drawbacks of broker-based messaging” – This section lays out some of the advantages and disadvantages of using a message broker. This is a very important section that makes some very valid points
- Page 94 3.3.5 “Competing receivers and message ordering” – This section describes how modern event brokers handle ordering messages.
- Page 95 3.3.6 “Handling duplicate messages” – This section explains how message brokers handle duplicate messages. This section points out some handy information, it describes how messages can get duplicated.
- Page 96 “Writing idempotent message handlers“ and “Tracking Messages and discarding duplicates” This is important information for when you design message handlers. The section on tracking messages has some good information worth reviewing again about storing id’s of already processed messages to create an idempotent message handler.
- Page 97 3.3.7 “Transactional messaging” This section talks about keeping your system in a consistent state when a service needs to update a database. It talks about distributed transactions and why they wont work in a microservice environment. It also mentions an interesting pattern The transactional outbox pattern, which uses a database table as a temporary message queue.
- Page 98 discuses using the Polling Publisher Pattern with transactional messaging.
- Page 99 “Publishing events by applying the transaction log trailing pattern“ I’ve seen this mentioned in other places before but this is the first time I have seen it actually explained complete with diagram.
- Page 100 continues by giving a list of software used for this purpose. LinkedIn uses Databus to interface with Oracle. While studying in college I took a course on Oracle. I saw the absolutely insanely absurd pricing policy, our entire class was taken back by it and were like GTFO and quickly decided never to invest another second into that debacle. Now companies are fleeing it, I feel psychic sometimes. I couldn’t see how any company could afford it.
- Page 100 in the list of tail logging software is a software called Eventuate created by the author, the link is to a github in the book, but this is the website for it It works with many protocols MySQL, Postgres and publishes to KAFKA this is handy
- Page 100 3.3.8 Libraries and Frameworks for messaging makes some very good points about how using the client library of a Message Broker ties the services to the broker and requires repeated boilerplate code. There are different libraries and frameworks that make this easier. I use Scala it has Lagom and others, many languages have frameworks for this.
- Pages 101 – 102 cover a basic example of using Eventuate Tram framework for messaging.
- Page 103 -104 3.4.1 Synchronous communication reduces availability starts the discussion about the downsides of synchronous communication in a microservice architecture
- Page 104 3.4.2 Eliminating synchronous interaction talks about using asynchronous interaction styles with microservices when a request needs data from more than one microservice to complete a request.
- Page 105 Replicate Data gives very helpful information about how to replicate data that a service needs to complete a request by subscribing to events from other services.
Chapter 4 Managing transactions with Sagas
One problem with Microservices is that they are distributed. In a distributed system when two or more services need to interact in order to complete an action, you need a plan for when one part of the series fails. When one part of a series of actions fails you need to undo anything any of the successful actions may have done. This is done with something called a Saga.
Pages 110 – 111 Starts the chapter out by telling a nice story to set the scene of the problem that Sagas are meant to address. This is some good insight for anyone not familiar with the situation a Saga solves.
Page 112 Section 4.1.2 The trouble with distributed transactions – points out that the traditional use of distributed transactions has some major downsides and should not be used with a Microservice Architecture.
Page 113 points out that Distributed transactions aka Two Phase Commits are not supported by some NoSQL databases like Mongo and Cassandra or by brokers like RabbitMQ and Apache Kafka. So really they are not compatible with Microservice Architectures unless you are doing it wrong LOL. They are also synchronous by default because the system must wait for all transactions to succeed, in a distributed world you can lose a network connection anytime. Bad news.
Page 114 Section 4.1.3 Using the Saga Pattern to maintain data consistency. This section starts to cover how the Saga pattern works.
Page 115 – 116 cover compensating transactions when part of a Saga fails. This seriously reminds me of functional programming, which I will probably write about some time later. In functional programming you can create functions that execute a series of other functions or not if one of the functions fail. Functional programming is starting to look like it pairs much better with Microservices than traditional OOP. There is a place for both in microservices though, use functional for operations that are non-mutative, use OOP for mutative operations.
Page 117 Section 4.2 Coordinating Sagas – This section quickly covers how a Saga should unfold, it quickly repeats what has been said and leads into the next subject which is Choreography vs Orchestration
Page 118 Section 4.2 Choreography based Sagas – This section covers how a choreography based Saga should operate. The discussion carries over to page 120 Page 119 lists the order for a successful Saga and the order for a failed Saga. Choreographed Sagas communicate with each other via events. Each service that takes part in the Saga listens for events and has an event handler. When a service finds an event it can handle it does so and fires another event for any interested service to also act accordingly. Choreography can lead to tighter coupling because services must know about each other.
Page 120 Reliable event based communication – This section cover some of the drawbacks of choreography based Sagas and continues onto page 121
Page 121 Benefits and Drawbacks of Choreography based Sagas – This small section quickly lists the pros and cons
Page 121 4.2.2 Orchestration based Sagas – This section describes orchestration based Sagas.
Page 123 Modeling Saga Orchestrators as State Machines – This section describes what a state machine is in the context of microservices. It gives a nice example and leads into page 124 with a nice diagram to explain the description of the state machine with microservices. This is a very handy section.
Page 125 Benefits and Drawbacks of Orchestration based Sagas – This section lists the good and the bad.
Page 126 Section 4.3 Handling the Lack of Isolation
Page 127 section 4.3.1 Overview of Anomalies – This section covers issues such as lost updates, dirty reads and fuzzy/non-repeatable reads
Page 128 section 4.3.2 Countermeasures for handling the lack of isolation – This section starts by mentioning some of the issues and counter measures then continues by explaining each type
Page 128 The structure of a Saga – This section has useful information about how transactions should work together throughout the lifetime of a Saga.
Page 129 Countermeasure Semantic Lock – This carries on to page 130 describing how to use fields in a table to mark at what stage a Saga is currently in. This is a pretty simple concept.
Page 130 CounterMeasure: Pessimistic view – Talks about reordering the steps of a Saga to help prevent some issues.
Pages 132 – 145 The Design of the Order Service and the create order Saga – These pages show an example of how a Saga should work complete with a Java code example using the authors Eventuate Tram Framework. Good information on these pages.
Chapter 5 Designing business logic in a microservice Architecture
Page 147 Section 5.1 Business Logic organization pattern – Mention inbound and outbound adapters for handling requests. This section mentions developing business logic with OOP or procedural approaches, it totally avoids a functional approach. I personally feel a mix of OOP and Functional is best. Very few people are familiar with Functional programming, but it is something I am getting deeply into. After many years of OOP I am simply tired of all of the BS boiler plate it causes. OOP causes too many pieces in a puzzle. Scala’s OOP and Functional abilities really pulled me to it, the more I learned it the more I hated Java. I seriously, seriously hate Java to the point my hatred forced me to Scala. I don’t feel like writing a full god damn paragraph of irritating boilerplate code to instantiate a single god damned object, thank you very much Java. When you see the amount of Java vs Scala to get work done you will grow to hate Java too. Scala is fairly hard to learn though because you can do so many things.
Page 149 Section 5.1.1 Designing Business Logic using the Transaction Script Pattern – This section explains how the transaction Script pattern works.
Page 150 Section 5.1.2 Designing business logic using the Domain Model pattern – This section starts the discussion about creating the business logic with Domain Driven Design principles. I am determined to learn how to use DDD concepts with Functional programming.
Page 151 Section 5.1.3 About Domain Driven Design – This section quickly covers some minor basics of DDD
Page 154 Section 5.2.2 Aggregates have explicit boundaries – This section gives the definition of an aggregate and continues to explain aggregates with a diagram of what an aggregate is on page 155
Page 155 Aggregates are consistency boundaries – This describes nicely how an aggregate controls the business invariants.
Page 155 Aggregate rules – This section lasts a few pages and covers the rules aggregates should obey.
Page 156 Rule #1 Reference only the aggregate root – Talks about how external services should only be able to accesss the aggregate root of an aggregate. Aggregates are similar to Microservices and each has a root which is basically it’s API
Page 156 Rule #2 Inter-aggregate references must use primary keys – This is a nice section that explains how aggregates are separate objects and each should be referred to by an ID as in a primary key instead of an object reference like creating a new object. This adds to improved loose coupling between aggregates.
Page 157 Rule #3 One Transaction creates or updates one aggregate – This section quickly covers why transactions should only update one aggregate and if you need to update more then you need to use the Saga pattern from chapter 4.
Page 158 Section 5.2.4 Aggregate granularity – This section basically covers Large vs Small aggregates it gives some pros and cons and has a nice diagram.
Page 159 Section 5.2.5 Designing business logic with aggregates – This section has a nice diagram showing the design of a service based on aggregates.
Page 160 Section 5.3 Publishing domain events – This section covers domain events. Domain events are things that have happened to an aggregate such as a state change. This section notes that changes are published as events for any interested party to consume for whatever purpose.
Page 160 Section 5.3.1 Why publish change events? – This helpful section lists reasons to publish domain events. There are a lot of good reasons listed here, too much to type out.
Page 161 section 5.3.2 What is a Domain event – This section defines what a domain event is and gives pointers on how you should create them. Domain events usually have an id attached to them
Page 161 Section 5.3.3 Event Enrichment – This useful section talks about enriching events with other metadata that future consumers may need. This is something I was thinking about doing with functional programming techniques as well. Basically I was thinking of passing a list of functions with the data they need, much the same as Sagas work, to a function. Much of what I am reading about Sagas and communication remind me of Functional programming techniques such as functors and monads. Why not send a list of functions to a function and let it handle the happy and sad paths? Sounds like a Saga to me. The more I read about functional programming the more I like it, it is easy like Math.
Page 162 Section 5.3.4 Identifying domain events – This section spills over onto page 163. It discusses Event Storming and gives a quick overview of what it is. I have an entire resources page dedicated to this subject.
Page 164 – 165 Section 5.3.5 Generating and publishing domain events – This is a nice section that covers the process of creating and publishing domain events.
Page 166 How to Reliable publish domain events? – This section repeats information from chapter 3 about using Eventuate Tram.
Page 167 Section 5.3.6 Consuming Domain Events – Domain events are published as messages to a message broker like Kafka for other consumers to find and act upon. This section mentions using Eventuate Tram instead of directly interacting with the Kafka API.
Pages 168-169 Section 5.4 Kitchen Service Business Logic – This section discusses the logic of one of the Services in the books imaginary app. Page 168 describes the diagram on page 169 which shows the structure of the Kitchen service pointing out the Aggregate and all the moving parts.
Page 169 Section 5.4.1 The ticket Aggregate – This section covers how aggregates should work. There is some useful information here covering the hows of aggregates.
Page 170 Structure of the Ticket class – talks about the ticket class and makes some good points about using object ids instead of passing objects because microservices are distributed.
Page 170 Behavior of the Ticket Aggregate – Shows the Ticket Aggregate class and describes how it works. This section describes the states of the Ticket aggregate aka it’s state machine. This is a very useful example.
Pages 173 – 174 Describe the different working parts of the imaginary app with a really nice diagram showing how all of the pieces of the Order Service work together to form a microservice.
Page 175 Section 5.5.1 The Order Aggregate – Covers the order aggregate giving a nice example and thorough walk through of the Order Aggregate and how it operates. There is a diagram to accompany the discussion which is helpful. This diagram shows examples of the Aggregates Value Objects. This is helpful to see how it relates to the subject. The discussion carries over to page 176 where it gives some example code of the Order Class.
Page 176 The Order Aggregate State Machine – This section gives a useful example of how a state machine works in and a nice diagram on page 177 that shows part of the state machine model for the Order Aggregate.
Pages 177-180 The Order Aggregate’s Methods – this long yet useful section covers the methods of the Order Aggregate and show a few pages of example code as part of the discussion.
Chapter 6 Developing Business Logic with event sourcing
Page 184 Section 6.1 Developing business logic using event sourcing – this section gives a quick definition and description of event sourcing. This section is useful. It talks about some of the pros and cons of Event Sourcing in microservices. Event sourcing pattern link
Page 185 Section 6.1.1 The trouble with traditional persistence – This section quickly covers the problems with trying to use the traditional data persistence pattern with microservices architectures. The next few sections and pages elaborate.
Page 185 Object-Relational impedance mismatch – This basically means that your object in your code doesn’t match the schema of your database. The funny thing is this mismatch goes away with properly designed microservices. These microservices will more closely match the structures of the original monolithic database. Basically what used to be tables becomes microservices where some tables live together under one microservice.
Page 186 – covers the rest of the trouble with traditional persistence including Lack of Aggregate History which means that you can’t figure out how your object got into the state it is because with traditional persistence you simply update table fields to represent the objects changed states. This makes auditing hard
Page 186 Implementing audit logging is tedious and error prone – This section discusses how audit logging works for tracking things like changes a user has made to an object which change it’s state etc. About the same as Aggregate History.
Page 186 Event Publishing is Bolted on to the Business logic – This quickly covers the fact that Event publishing wont work very well with the traditional CRUD persistence pattern because things get out of sync.
Page 186 Section 6.1.2 Overview of event sourcing – This is the best description of Event Sourcing I have seen so far. “Event sourcing is an event-centric technique for implementing business logic and persisting aggregates. An aggregate is stored in the database as a series of events. Each event represents a state change of the aggregate. An aggregate’s business logic is structured around the requirement to produce and consume these events.”
Page 186 Event Sourcing persists aggregates using events – This section has a nice diagram of a table with fields that demonstrates saving events to a database. It covers saving then replaying the events to rebuild the aggregate/object. This is an important point because it points out how persistence in a Microservice Architecture is different from monoliths. Event sourcing allows your application to spin up more microservice nodes to handle more traffic when needed. This is done by replaying the events of objects, while each new microservice node handles a different section of the work from the events list.
Page 188 Events Represent state changes – this nice section covers what kind of data events should contain. All events are different and each needs to carry different information for various reasons.
Page 189 Aggregate Methods are all about events – This section explains that to use event sourcing you must refactor command methods into more than one method to match the event states.
Page 191 covers the process for creating and updating aggregates by selecting and applying events.
Page 191 Event sourcing-based order aggregate – This section gives an example of the the use of Event sourcing by showing some example code of the Order class refactored to use Event sourcing. This is a very useful example.
Page 194 Using Polling to publish events – This is when an event publisher polls a table for events and publishes them to the broker. This section discusses the problems with this approach and the next few sections discuss a solution.
Page 195 Using Transaction log tailing to reliably publish events – Doesn’t say much here other than log tailing is more reliable and will be explained better later.
Page 195 Section 6.1.5 Using Snapshots to improve performance – This section explains how snapshots reload aggregates state efficiently. Basically instead of loading all of the events for a particular entity and replaying them all, you load a snapshot from a point in history and replay from that point. Not covered in this section ->This is also useful if you have a service with multiple nodes, that is a service running the same code on multiple cloud instances for example. This way as the system needs more resources it can spin up new nodes in the cloud and have them start from their own snapshots for the entities they recreate the state of.
Page 196 Section 6.1.6 Idempotent message processing – This section briefly covers the fact that event messages should only produce a result once and how to enforce this. This section talks about Eventuate Tram more.If you are using Java this sounds like a good solution. I’m using Scala so I could maybe use Eventuate by implicit conversion, but I am interested in AKKA, KAFKA, Lagom, Cassandra, Spark. Scala lets you use a very large amount of Java though. When I get bored maybe I’ll try eventuate with Scala and write an article.
Page 198 Section 6.1.7 Evolving Domain Events – This section makes important points about some of the main reasons your events may change over time and some of the things you can do.
Page 199 Section 6.1.8 Benefits of Event Sourcing – This section covers a few of the great benefits of Event Sourcing like Reliably publishing domain events, Preserving the history of an aggregate, Avoiding Object/relational mismatchs and providing developers with a time machine. Event sourcing provides some awesome benefits.
Page 200 Section 6.1.9 Drawbacks of event sourcing – This covers some of the drawbacks such as a harder to learn programming model, it has the complexity of a messaging based application, evolving events is hard, deleting data thanks to GDPR is harder, querying the event store is harder.
Page 201 Evolving events can be tricky – This short section talks about the complications that can occur when you have made changes to an event.
Page 201 Deleting Data is Tricky – This section mentions using encryption of private data with a unique key per user so that you can effectively delete personal user data to be in compliance with GDPR. This is some handy information.
Page 202 Section 6.2 Implementing an event store – This section talks about event storage and how they should operate. It then lists a couple of event stores, Event Store, Lagom(for Scala and Java this is what I’ll use), Axon( for Java) and Eventuate( for Java) If I were using Java I’d go with Eventuate it sounds great, if you are using Java try it to learn some things. You should research and decide what is best for your language.
Page 203 How the Eventuate local event store works – This section talks about how the event store works theoretically in a way you can implement on your own without Eventuate. I’ve still got to dig into how Lagom does this. One of my goals is to understand Lagom before I use it to build a large system. I’m older now. I’ve made quick decisions in the past and misunderstood how something operated and made a ball of mud.
Page 209 Section 6.3 Using Sagas and Event Sourcing together – This section talks about some of the complexities encountered when using Event Sourcing with the Saga Pattern.
Page 210 Section 6.3.1 Implementing choreography based sagas using event sourcing – This short section explains that choreography based Sagas in an Event Sourced system is harder to implement and why. This section has useful information.
Page 211 Section 6.3.2 Creating an Orchestration based Saga – This section carries on to page 212 and explains how a microservice system that wants to implement Orchestration based Sagas should go about doing so. It also makes a comparison and gives information about using an RDBMS vs a NoSQL database. There is a nice diagram explaining the process on page 212
Page 212 Idempotent Command Message Handling + Atomically sending reply messages – This section has some really useful information related to how Saga participants can communicate with the Saga Orchestrator.
Page 216 Section 6.3.4 Implementing Saga Orchestrators using event sourcing – This section gives some good information about creating Event sourced Saga orchestrators.
Page 216 Sending command messages reliably – This section has some great information about the process that is used to send command messages in an Event sources orchestration based system.
Page 218 Processing replies exactly once – This section basically summarizes the process of idempotent message handling.
Chapter 7 Implementing Queries in a Microservice Architecture
Page 222 Section 7.1.2 Overview of the API Composition Pattern – This section covers how the API Composition pattern has the methods of the API query the needed services and build up a response. Link to the pattern.
Page 224 Section 7.1.4 API Composition design issues – This covers some of the design issues when implementing the API Composition pattern such as deciding which component will be the API composer and how to write efficient logic. This section makes very important points. One thing I thought about while reading this section is if you are using REST or RPC, what if one of the services that need to be queried is failing? Then your entire query is holding up resources. What if you used the same process of event sourcing to build the query so that nothing hangs up. Have a query orchestrator use a Saga like pattern to build the query.
Page 227 Section 7.1.5 The benefits and drawbacks of the API composition pattern – This section covers the pros and cons of this pattern such as increased overhead, reduced availability and lack of transactional data consistency.
Page 228 Section 7.2 Using the CQRS pattern – Link to CQRS pattern. This simply explains some of the reasons to use the CQRS pattern.
Page 231 A challenging single service query: findAvailableRestaurants() – This section has some useful information about choosing the correct database to store your data for query purposes.
Page 232 Section 7.2 Overview of CQRS + CQRS Separates Commands from Queries – These sections give an overview and definition of CQRS. It continues to page 233 with a nice diagram that demonstrates the process. This is a very useful section.
Page 235 Section 7.2.3 The benefits of CQRS – This section lists the benefits of CQRS and has four sub-sections that go into deeper detail on the following *Enables the efficient implementation of queries in a microservice architecture * Enables the Efficient implementation of diverse queries * Enables Querying in an event sourcing based application * Improves separation of concerns.
Page 236 Section 7.2.4 The Drawbacks of CQRS – this section lists some of the drawbacks in two sections *More complex architecture * Dealing with the replication lag These sections contain very useful information.
Page 237 – 239 Section 7.3.1 Choosing a view datastore – This section covers some of the aspects you need to consider when choosing a database for your CQRS views/queries. It notes some of the various strengths and weaknesses of different database types.
Page 239 Section 7.3.2 Data Access Module Design – This section makes some good points about DAO classes and how they should handle events. It covers Idempotentcy with some good ideas on how to implement it. It finishes by talking about how to deal with eventual consistency in a query view.
Page 241 Section 7.3.3 Adding and updating CQRS views – This section has some good information about the problems you will face when adding or updating CQRS view modules and gives some example solutions.
Page 242 – 252 Gives an example of implementing CQRS views using AWS DynamoDB. There is a lot of useful information in these pages.