简体   繁体   中英

How to approach a Query that changes the systems state in CQRS?

Consider a situation in a CQRS system where a query would change the system's state. For instance, a cache update, a background job, or some other sync or async task. My question is how to handle this situation.

One might say that if you ever faced a condition where a Query has to trigger some changes to your system, then your architecture is flawed you've probably done something wrong, but I think this kind of this situation is something quite common and there is no way to avoid it.

However, the question remains how should our approach be for solving this problem?

Also to give a little more context to work, let's say you have an API endpoint called get-stuff , when calling get-stuff , an api handler issues a query to a query handler (which is probably a synchronous function call. The query handler retrieves the data and returns the results to the caller functions/services. But we have a business requirement to schedule a background job(for some reason...) the first time a user calls get-stuff each day, also we use a caching mechanism in front of the database, whenever new data is fetched by the user, and the cache has to be updated. So as you can see a simple query call needs to change some states and write some data. The question here is how to add these functionalities without damaging our principles and architecture.

I have to add that this is not an exact situation that I personally faced. I only got curious about it and could not find a good answer online. I can not describe an exact scenario but I appreciate a general approach or answer that can be used in different types of situations.

ps: I only found this question, but the answers do not fulfill my needs and I believed their not practical enough.

Two points to make clear:

  • Command vs. Query is based on the desire of something outside the system to change the system's state

  • There's no hard prohibition on a command resulting in a value

So if a request from outside doesn't intrinsically express a desire to update state, it's a query. The process of handling that request may choose to update some state (especially if the state it's updating is non-authoritative, eg a cache) for its own purposes, but that implementation detail cannot change the essential query-ness of the request. GetItemsMatchingPredicate doesn't intrinsically update state.

If the request does intrinsically express a desire to change state, it's a command. For atomicity and consistency reasons (CQRS, absent certain assumptions about infrastructure which it might often be advantageous for one not to make, tends to imply something less than absolute strong consistency), that request might want to include some bit of the updated state in an associated response: that does not make it a query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM