This allows the client to update its representation of the affected resources, without having to perform a follow up query immediately
The catch is in the implication here. What you’re effectively saying is:
I have to fire one less request when I merge the two requests (i.e. the command and subsequent query) into one.
What you’re saying is not wrong, but you are violating the core tenet of CQRS, which it is literally named after: Command Query Responsibility Segregation.
You are correct that merging these two requests saves your frontend a small bit of overhead performance related to the firing and waiting for a second web request (but we can definitely argue about whether this overhead is significant or negligible, which I’ll get into in a bit).
If you’re dealing with a slow network connection, this difference can be non-negligible. e.g. I’ve developed 3G mobile software where network requests were minimized as much as possible due to spotty connections.
However, CQRS isn’t focused on optimizing the performance of the frontend, it’s focused on maintainability and scalability of the backend. This will also benefit the frontend, but in an indirect way. CQRS allows for scalability of your read store (since it is then separated from your write store), thus lowering the overall time of your second request; instead of preventing you from having to fire that second request.
I do want to point out here that for connections with no strict limitations, the cost of performing a second call is negligible and not reasonably spotted by an end user. If there is a noticeable lag due to a second request being fired, on a good connection, that actually suggests that your system should be scaled up (as the requests aren’t being handled in a reasonable time), which is what CQRS helps you with.
If this is the situation you find yourself in, then undoing the command/query segregation is effectively perpetuating your performance issues instead of improving them.
Do you have to use CQRS? Of course not. Just like any other principle or pattern, it exists to fix a particular problem. If the problem doesn’t exist in your scenario (or is not considered a problem), then the principle/pattern is not needed.
But your CQRS “variation” is actually undoing what is essentially the first and only commandment of CQRS: separating your data operations from your data queries.
Does that mean you shouldn’t do what you’re doing? No, not necessarily. But I wouldn’t call it CQRS anymore as it’s quite the opposite.
which possibly would return data from the out-of-date read model, since read models can be updated asynchronously
This is a cart-before-horse situation. If you don’t want to deal with the consequences of having your read store updated asynchronously, then don’t asynchronously update your read store.
It sounds facetious but it really is as simple as that. Asynchronicity has its upsides and its downsides (just like everything), and if you don’t want the downsides, then don’t do it.