Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CQRS with Legacy Systems

I'm looking to convert a relatively new web-based application with a clear domain model over to more of a CQRS style system. My new application is essentially an enhanced replacement of an older existing system.

The existing systems in my organization share a set of common databases, which are updated by an untold number of applications (developed via the Chaos Method) that exist in silos throughout the company. (As it stands, I believe that no single person in the company can identify them all.)

My question is therefore about the read model(s) for my application. Since various status changes, general user data, etc. are updated by other applications outside my control, what's the best way to handle building the read models in such a way that I can deal with outside updates, but still keep things relatively simple?

I've considered the following so far:

  1. Create Views in the database for read models, that read all tables, legacy and new
  2. Add triggers to existing tables to update new read model tables
  3. Add some code to the database (CLR Stored proc/etc [sql server]) to update an outside datastore for read models
  4. Abandon hope

What is the general consensus on how to approach this? Is it folly to think I can bring order to a legacy system without fully rewriting everything from scratch?

like image 737
reallyJim Avatar asked Jun 19 '12 14:06

reallyJim


People also ask

When should CQRS be used?

When to use CQRS pattern. Consider CQRS for the following scenarios: Collaborative domains where many users access the same data in parallel. CQRS allows you to define commands with enough granularity to minimize merge conflicts at the domain level, and conflicts that do arise can be merged by the command.

What problem does CQRS solve?

CQRS is a popular architecture pattern because it addresses a common problem to most enterprise applications. Separating write behavior from read behavior, which the essence of the CQRS architectural pattern, provides stability and scalability to enterprise applications while also improving overall performance.

What is the benefit of CQRS in microservices?

The concept of CQRS uses messages to describe commands, events, queries to deal with the Command Model and sync changes and extracts data from the Query model. This is hugely beneficial in enabling microservices and taking a monolith first approach with your application.

How is CQRS design pattern related to microservices?

CQRS is one of the important pattern when querying between microservices. We can use CQRS design pattern in order to avoid complex queries to get rid of inefficient joins. CQRS stands for Command and Query Responsibility Segregation. Basically this pattern separates read and update operations for a database.


2 Answers

I've used option #1 with success. Creating views to demoralize the data to create a read model is a viable option depending on the complexity of the write database(s). Meaning, if it is relatively straight forward joins that most developers can understand then I would take a closer look to see if it's viable for you. I would be careful with having too much complexity in these views.

Another thing to consider is periodic polling to build and update similar to a traditional reporting databases. Although not optimal in comparison to a notification, depending on how stale your read model can be, this might also be an option to look at.

like image 164
Derek Comartin Avatar answered Sep 27 '22 19:09

Derek Comartin


I once was in a similar situation, the following steps was how i did it:

To improve the legacy system and achieve cleaner code base, the key is to take over the write responsibility. But don't be too ambitious as this may introduce interface/contract changing which makes the final deployment risky.

  1. If all the write are fired through anything except direct sql updates, keep them backward compatible as possible as you can. Take them as adapters/clients of your newly developed command handlers.

  2. Some of the write are direct sql updates but out of your control
    Ask the team in charge if they can change to your new interface/contract?
    If no, see step 3.

  3. Ask if they can tolerate eventual consistency and are willing to replace the sql updates with database procedures?
    If yes, put all the sql updates in the procedures and schedule a deployment and see step 4.
    If no, maybe you should include them in your refactoring.

  4. Modify the procedure, replace the sql updates with inserting events. And develop a backend job to roll the events and publish them. Make your new application subscribing these events to fire commands to your command handlers.

  5. Emitting events from your command handlers and use them to update the tables that other applications used to consume.

  6. Move to the next part of the legacy system.

like image 25
Yugang Zhou Avatar answered Sep 27 '22 19:09

Yugang Zhou