About Microservices.io

Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action and the creator of the original CloudFoundry.com. His latest startup is eventuate.io, a microservices application platform.

Learn more about microservices

Chris offers a comprehensive set of resources for learning about microservices including articles, an O'Reilly training video, and example code. Learn more

Microservices consulting and training

Chris offers a comprehensive consulting services, workshops and hands on training classes to help you use microservices effectively. Get advice

Example microservices applications

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

Get the book: Microservice patterns

Signup for the newsletter

A new microservices application platform that solves distributed data management problems.

Join the microservices google group

Pattern: Command Query Responsibility Segregation (CQRS)


You have applied the Microservices architecture pattern and the Database per service pattern. As a result, it is no longer straightforward to implement queries that join data from multiple services. Also, if you have applied the Event sourcing pattern then the data is no longer easily queried.


How to implement queries in a microservice architecture?


Split the application into two parts: the command-side and the query-side. The command-side handles create, update, and delete requests and emits events when data changes. The query-side handles queries by executing them against one or more materialized views that are kept up to date by subscribing to the stream of events emitted when data changes.


Customers and Orders is an example of an application that is built using Event Sourcing and CQRS. The application is written in Java, and uses Spring Boot. It is built using Eventuate, which is an application platform based on event sourcing and CQRS.

This application maintains a CQRS view in MongoDB. Each document contains information about a customer and their orders. The view is updated by subscribing to customer and order events:

@EventSubscriber(id = "orderHistoryWorkflow")
public class OrderHistoryViewWorkflow {

  private OrderHistoryViewService orderHistoryViewService;

  public OrderHistoryViewWorkflow(OrderHistoryViewService orderHistoryViewService) {
    this.orderHistoryViewService = orderHistoryViewService;

  public void createCustomer(DispatchedEvent<CustomerCreatedEvent> de) {
    String customerId = de.getEntityId();
    orderHistoryViewService.createCustomer(customerId, de.getEvent().getName(),

  public void createOrder(DispatchedEvent<OrderCreatedEvent> de) {
    String customerId = de.getEvent().getCustomerId();
    String orderId = de.getEntityId();
    Money orderTotal = de.getEvent().getOrderTotal();
    orderHistoryViewService.addOrder(customerId, orderId, orderTotal);

  public void orderApproved(DispatchedEvent<OrderApprovedEvent> de) {
    String customerId = de.getEvent().getCustomerId();
    String orderId = de.getEntityId();
    orderHistoryViewService.approveOrder(customerId, orderId);  }

  public void orderRejected(DispatchedEvent<OrderRejectedEvent> de) {
    String customerId = de.getEvent().getCustomerId();
    String orderId = de.getEntityId();
    orderHistoryViewService.rejectOrder(customerId, orderId);

OrderHistoryViewService uses Spring Data for MongoDB to update MongoDB.

There are several example applications that illustrate how to use event sourcing.

Resulting context

This pattern has the following benefits:

  • Necessary in an event sourced architecture
  • Improved separation of concerns = simpler command and query models
  • Supports multiple denormalized views that are scalable and performant

This pattern has the following drawbacks:

  • Increased complexity
  • Potential code duplication
  • Replication lag/eventually consistent views

See also

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