Commands and Queries
A general is just as good or just as bad as the troops under his command make him.
~ Douglas McArthur
We are currently working on a project to protect vulnerable people from phishing attempts. The project itself will be released in the beginning of next year while we are preparing our last touches to it (and to be honest enjoying our holidays too).
We decided to code it using the latest version of Ruby on Rails. Rails has grown so much as a framework from when I started using it back in the early 2000s. I’m really impressed by what the team has archived with this new version (it’s never been simpler to write and realease software when you have a small saas business).
As we were writing our code we didn’t realy like how we were adding functionality to the controllers and the awkwardness of writing tests for the controllers themselves (I much rather have some higher level tests that make sure a feature works using something like cucumber or cabybara).
There are many approaches to organise your code; Rails projects are known for creating a Service
object and
put all the business logic into a Service
classes. The prolem I have with the service concept is that it
usually muddles the waters a little bit and you either end up with a lot of small services (not that bad) or
a bunch of really big service classes (not adivsable).
In order to write sustainable code I prefer to write classes that are small and do one thing only; I much rather have more smaller classes that meaninfully reveal intent, than big balls of mud that do to much.
Command Query Separation
One approach to clean up your codebase is using Command Query Separation. In a nutshell this means you separate your application logic (or business logic) into commands and queries.
When you want some data you’ll be issuing a query and when you want to modify data you’ll issue a command; it’s pretty straight forward.
The beauty of this comes into play when you are working on the project; because of this separation, you always know where to look for the code (either in the commands or queries subdirectories/modules).
In our implementaion Commands and Queries are very similar in structure even though they do different things conceptually.
Let’s see a command in action:
The command itself looks something like this:
This particular command uses the User
model and the ActiveRecord
method find_or_create_by
to either find
and existing user or creating a new “guest” user. If you are a purist you’d (not wrongly) argue that a
Command
should not have any return values. Normally I would agree with you, but we chose not to add more
complicated infrastructure to the project (like event queues, etc.) and instead play along with what Rails
has to offer.
The included Command
module is fairly straight forward – when included you will only have to implement
the execute
method (which has access to the subject
– the arguments passed in the with
class method).
Queries are similar to Commands (they share some of the code), but instead of an execute
method
you have to implement an answer
method. The resulting code looks like something like this:
There are cases where we wanted to change the calling method to the commands and queries to make the code more readable.
An example of this would be when we are checking if a user is allowed to perform some action:
The way we do this is by adding this simple line of code inside the UserService
query:
By separating our code in command and queries we create highly readable code that at the same time is easy to find in a growing codebase.
Building a command and queries infrastructure inside your Rails application is fairly simple (we considered releasing this as a gem so you can add it to your rails project, but haven’t gotten to it yet).
How do you organise the code inside your applications? I’d love to hear from you!