I have already talked why it’s important to have a good name for your software here, today I want to dig a little deeper into naming, this time on a more technical level: Naming events.
At BetterDoc we’re currently embarking on a journey towards an event driven architecture. One part of what we’re discovering right now is the importance of having a good name for our events.
When you are consuming an event from a topic or a queue you need to be able to quickly understand why the event has been produced and pushed into a topic or a queue.
Of course you could “delegate” the process of understanding by referring to an epic documentation where each event is described in as much detail as you can possibly image.
But you know what? People don’t read documentation.
Developers are no exception. Unless something goes horribly wrong we all simply assume that we make the right assumptions and simply start using “that thing”.
So if we cannot be sure that people are paying attention to the details by reading the documentation we have to make it easy for them to get the right idea simply by looking at what is in front of them. The best software vendors have understood this principle. Take Apple as an example: Nobody needs to read a manual any more when they start using their iPhone - the concepts are easy to grasp and easy to understand.
Getting back to our event driven architecture we understood that finding the right name for an event is essential as that name needs to convey a large piece of information about the event itself. Why was it produced? What happened at that? What did the system do?
Let’s take an example: Finding a specialist.
This is the heart of our BetterDoc service: Our research team finds a physician that can do exactly what a patient needs. We call that physician a specialist and the process of finding this specialist we call matching.
Within our application the researcher associates the physician selected to the patients profile. At that time we generate an event that other parts of our application landscape can consume and react to the selection.
So how do we name this event?
It sounds too ambiguous.
Is it a match for a specialist? Or a match for a diagnosis? Or a match for a treatment? Or a match to some sort of statistical property? There are simply to many ways of interpreting something like
We need to find a better name.
That sounds better, right?
We have removed a lot of the ambiguity and have narrowed it down to the actual match we’re interested in.
But what does it tell us about the actual process? Is the event generated when a researcher starts the matching process? It it generated when the matching process is completed? How do we know the match is successful? There possibilities for reaching a wrong interpretation too quickly are still to large.
So we came up with a naming scheme that introduces the following prefixes:
WILL_MATCH_SPECIALIST) signalizes that some action is about to happen but has not happened yet. For example a
WILL_SEND_EMAILevent signalizes that the system decided to communicate with a user via email but doesn’t tell us anything about if the email was actually sent out successfully.
DID_MATCH_SPECIALIST) signalizes that some action has happened successfully. For example a
DID_MATCH_SPECIALISTevent signalizes that a matching has been performed and that the result was successful. A specialist was selected for a patient.
ERR_MATCH_SPECIALIST) signalizes tha something has gone wrong during the execution of an action. For example an
ERR_SEND_EMAILevent signalizes that an error occured during the actual sending of an email.
SYS_INIT_SPECIALIST) signalizes that some internal system wants the consumers to perform a special kind of action. For example a
SYS_INIT_SPECIALISTevent signalizes the consumer is expected to perform an initialization on a specialist, whose data is included in the event.
SYSevents should be used with care as they focus on the system rather than the actual domain - but sometimes looking at the system from a system’s perspective simply is necessary.
The structure loosely follows the
begin ... rescue (or
try ... catch) exception handling mechanism.
Within a piece of Ruby code we could for example do something like this:
produce_event('WILL_MATCH_SPECIALIST') begin execute_specialist_selection produce_event('DID_MATCH_SPECIALIST') rescue produce_event('ERR_MATCH_SPECIALIST') end
By having that simple naming scheme we already have a pretty good understanding of why the event was being generated. It still doesn’t free us from having a detailed documentation (for example we need to know what kind of data is sent within the event, how that data is structured, etc.) but it gives a clear initial impression.