Pattern: Command-side replica

pattern   service collaboration   implementing commands  

Want to learn more about this pattern?

Take a look at my self-paced, online bootcamp that teaches you how to use the Saga, API Composition, and CQRS patterns to design operations that span multiple services.

The regular price is $395/person but use coupon NPXJKULI to sign up for $95 (valid until December 25th, 2024)

Context

You have applied the Microservices architecture pattern and the Database per service pattern. As a result, a service that implements a system command often needs to query other services. For example, the createOrder() command is implemented by the Order Service, which needs to retrieve the restaurant’s menu Restaurant Service in order to price and validate the line items.

One option is for the Order Service to query the Restaurant Service each time. The query can either be implemented synchronously using, for example, or asynchronously as a saga step. However, this approach has several drawbacks, which can be partially mitigated by caching, including more network traffic and a runtime dependency on the Restaurant Service.

An alternative approach is to replica the restaurants’ menus to the Order Service.

Problem

How can a service that implements a command retrieve data from another service?

There are five dark energy forces:

  • Simple components - simple components consisting of few subdomains are easier to understand and maintain than complex components
  • Team autonomy - a team needs to be able to develop, test and deploy their software independently of other teams
  • Fast deployment pipeline - fast feedback and high deployment frequency are essential and are enabled by a fast deployment pipeline, which in turn requires components that are fast to build and test.
  • Support multiple technology stacks - subdomains are sometimes implemented using a variety of technologies; and developers need to evolve the application’s technology stack, e.g. use current versions of languages and frameworks
  • Segregate by characteristics - e.g. resource requirements to improve scalability, their availability requirements to improve availability, their security requirements to improve security, etc.

There are five dark matter forces:

  • Simple interactions - an operation that’s local to a component or consists of a few simple interactions between components is easier to understand and troubleshoot than a distributed operation, especially one consisting of complex interactions
  • Efficient interactions - a distributed operation that involves lots of network round trips and large data transfers can be too inefficient
  • Prefer ACID over BASE - it’s easier to implement an operation as an ACID transaction rather than, for example, eventually consistent sagas
  • Minimize runtime coupling - to maximize the availability and reduce the latency of an operation
  • Minimize design time coupling - reduce the likelihood of changing services in lockstep, which reduces productivity

Solution

The solution consists of the following elements:

  • Command service - the service that implements the command.
  • Provider service - the service that owns the data that the command service needs
  • Replica database - a read-only replica of the data from the provider service. The command service keeps the replica up to data by subscribing to Domain events published by the provider service

Resulting context

Benefits

This pattern resolves the following forces:

  • Support multiple technology stacks - the replica database can use a technology stack that’s more optimized to support the command
  • Segregate by characteristics - the provider service is no longer invoked by the command and so might need to be as performant or available
  • Simple interactions - the command is simpler since it no longer needs to interact with the provider service
  • Efficient interactions - the command is more efficient since it no longer needs to interact with the provider service
  • Prefer ACID over BASE - the replica is potentially stale
  • Minimize runtime coupling - runtime coupling is reduced since the the command no longer needs to interact with the provider service

Drawbacks

This pattern potentially fails to resolve the following forces:

  • Simple components - makes the command service more complicated since it needs to maintain the replica. It also complicates the provider service since it must publish the events.
  • Team autonomy - the provider service’s team might need to coordinate more frequently with command service team due to increased design-time coupling (see below)
  • Fast deployment pipeline - the command service’s deployment pipeline might be slower since it needs test the replica
  • Segregate by characteristics - potentially increased since, for example, if the replica database contains regulated data (e.g. PII) then the command service might be more complicated.
  • Simple interactions - potentially more complicated since the provider service’s commands must publish events
  • Efficient interactions - potentially less efficient since the provider service might publish a large volume of events
  • Minimize design-time coupling - risk of tight design-time coupling between services, since the command service needs to know about the structure of the data that is replicated and potentially its lifecycle events.

See also

  • Eventuate, which is a platform for developing transactional business applications.

Learn more

  • My book Microservices patterns describes this pattern in a lot more detail
  • Take a look at my self-paced, online bootcamp that teaches you how to use the Saga, API Composition, and CQRS patterns to design operations that span multiple services.

pattern   service collaboration   implementing commands  


Copyright © 2024 Chris Richardson • All rights reserved • Supported by Kong.

About Microservices.io

Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action, the creator of the original CloudFoundry.com, and the author of Microservices patterns.

ASK CHRIS

?

Got a question about microservices?

Fill in this form. If I can, I'll write a blog post that answers your question.

NEED HELP?

I help organizations improve agility and competitiveness through better software architecture.

Learn more about my consulting engagements, and training workshops.

LEARN about microservices

Chris offers numerous other resources for learning the microservice architecture.

Get the book: Microservices Patterns

Read Chris Richardson's book:

Example microservices applications

Want to see an example? Check out Chris Richardson's example applications. See code

Virtual bootcamp: Distributed data patterns in a microservice architecture

My virtual bootcamp, distributed data patterns in a microservice architecture, is now open for enrollment!

It covers the key distributed data management patterns including Saga, API Composition, and CQRS.

It consists of video lectures, code labs, and a weekly ask-me-anything video conference repeated in multiple timezones.

The regular price is $395/person but use coupon NPXJKULI to sign up for $95 (valid until December 25th, 2024). There are deeper discounts for buying multiple seats.

Learn more

Learn how to create a service template and microservice chassis

Take a look at my Manning LiveProject that teaches you how to develop a service template and microservice chassis.

Signup for the newsletter


BUILD microservices

Ready to start using the microservice architecture?

Consulting services

Engage Chris to create a microservices adoption roadmap and help you define your microservice architecture,


The Eventuate platform

Use the Eventuate.io platform to tackle distributed data management challenges in your microservices architecture.

Eventuate is Chris's latest startup. It makes it easy to use the Saga pattern to manage transactions and the CQRS pattern to implement queries.


Join the microservices google group