In my web app I'm tracking view counts on pages.
Right now, the action in the controller issues a command to the data layer to increment the view count on the model before returning the result of the query.
This action seems to break the rules of Command-Query-Separation, since with the request the user agent is submitting a query and unwittingly issuing a command (to increment the view count)
What architectural decisions need to be taken to maintain the Command-Query-Separation in this action?
You should consider CQS relative to the conceptual level of the operation in question. Here are some examples that all seem to violate CQS, but only do so on a different conceptual level:
ReadFile
call on a file system object does not modify the file - but it canupdate the last accessed timestamp on the file.FindById
call to a repository should not change the database - but it can very well add the queried object to a cache.These examples have one thing in common: They maintain the state of the model
the client works on, but they do modify data outside of that model. And this is not a violation of CQS.
Another way to see this is through the principle of least surprise. A client of the above mentioned REST API would not expect the model to change with a GET request, but he doesn't care if the API updates a statistical counter.