@@ -145,7 +145,6 @@ <h2>Mapping our requirements to our domain</h2>
145145 < span class ="n "> expect</ span > < span class ="p "> (</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> issue</ span > < span class ="o "> .</ span > < span class ="n "> state</ span > < span class ="p "> )</ span > < span class ="o "> .</ span > < span class ="n "> to</ span > < span class ="p "> (</ span > < span class ="n "> equal</ span > < span class ="p "> (</ span > < span class ="n "> IssueState</ span > < span class ="o "> .</ span > < span class ="n "> AwaitingTriage</ span > < span class ="p "> ))</ span >
146146</ code > </ pre > </ div >
147147
148-
149148< p > We’re introducing a new concept - Issues now have a state, and a newly reported
150149issue begins in the AwaitingTriage state. We can quickly add a command and
151150handler that allows us to triage an issue.</ p >
@@ -161,7 +160,6 @@ <h2>Mapping our requirements to our domain</h2>
161160 < span class ="n "> uow</ span > < span class ="o "> .</ span > < span class ="n "> commit</ span > < span class ="p "> ()</ span >
162161</ code > </ pre > </ div >
163162
164-
165163< p > Triaging an issue, for now, is a matter of selecting a category and priority.
166164We’ll use a free string for category, and an enumeration for Priority. Once an
167165issue is triaged, it enters the AwaitingAssignment state. At some point we’ll
@@ -180,7 +178,6 @@ <h2>Mapping our requirements to our domain</h2>
180178 < span class ="n "> uow</ span > < span class ="o "> .</ span > < span class ="n "> commit</ span > < span class ="p "> ()</ span >
181179</ code > </ pre > </ div >
182180
183-
184181< p > At this point, the handlers are becoming a little boring. As I said way back in
185182the first part [https://io.made.com/blog/introducing-command-handler/], commands
186183handlers are supposed to be boring glue-code, and every command handler has the
@@ -225,7 +222,6 @@ <h2>Mapping our requirements to our domain</h2>
225222 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> email_sender</ span > < span class ="o "> .</ span > < span class ="n "> send</ span > < span class ="p "> (</ span > < span class ="n "> email</ span > < span class ="p "> )</ span >
226223</ code > </ pre > </ div >
227224
228-
229225< p > Something here feels wrong, right? Our command-handler now has two very distinct
230226responsibilities. Back at the beginning of this series we said we would stick
231227with three principles:</ p >
@@ -290,7 +286,6 @@ <h2>Mapping our requirements to our domain</h2>
290286 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> email_sender</ span > < span class ="o "> .</ span > < span class ="n "> send</ span > < span class ="p "> (</ span > < span class ="n "> email</ span > < span class ="p "> )</ span >
291287</ code > </ pre > </ div >
292288
293-
294289< p > We don’t really need a unit of work here, because we’re not making any
295290persistent changes to the Issue state, so what if we use a view builder instead?</ p >
296291< div class ="codehilite "> < pre > < span > </ span > < code > < span class ="k "> class</ span > < span class ="nc "> SendAssignmentEmailHandler</ span >
@@ -312,7 +307,6 @@ <h2>Mapping our requirements to our domain</h2>
312307 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> email_sender</ span > < span class ="o "> .</ span > < span class ="n "> send</ span > < span class ="p "> (</ span > < span class ="n "> email</ span > < span class ="p "> )</ span >
313308</ code > </ pre > </ div >
314309
315-
316310< p > That seems better, but how should we invoke our new handler? Building a new
317311command and handler from inside our AssignIssueHandler also sounds like a
318312violation of SRP. Worse still, if we start calling handlers from handlers, we’ll
@@ -386,7 +380,6 @@ <h2>Mapping our requirements to our domain</h2>
386380< span class ="n "> bus</ span > < span class ="o "> .</ span > < span class ="n "> handle</ span > < span class ="p "> (</ span > < span class ="n "> cmd</ span > < span class ="p "> )</ span >
387381</ code > </ pre > </ div >
388382
389-
390383< p > Here we have a bare-bones implementation of a message bus. It doesn’t do
391384anything fancy, but it will do the job for now. In a production system, the
392385message bus is an excellent place to put cross-cutting concerns; for example, we
@@ -404,7 +397,6 @@ <h2>Mapping our requirements to our domain</h2>
404397 < span class ="k "> return</ span > < span class ="s2 "> ""</ span > < span class ="p "> ,</ span > < span class ="mi "> 201</ span > < span class ="p "> ,</ span > < span class ="p "> {</ span > < span class ="s2 "> "Location"</ span > < span class ="p "> :</ span > < span class ="s2 "> "/issues/"</ span > < span class ="o "> +</ span > < span class ="nb "> str</ span > < span class ="p "> (</ span > < span class ="n "> issue_id</ span > < span class ="p "> )</ span > < span class ="p "> }</ span >
405398</ code > </ pre > </ div >
406399
407-
408400< p > Not much has changed here - we’re still building our command in the Flask
409401adapter, but now we’re passing it into a bus instead of directly constructing a
410402handler for ourselves. What about when we need to raise an event? We’ve got
@@ -425,7 +417,6 @@ <h2>Mapping our requirements to our domain</h2>
425417 < span class ="n "> cmd</ span > < span class ="o "> .</ span > < span class ="n "> assigned_by</ span > < span class ="p "> ))</ span >
426418</ code > </ pre > </ div >
427419
428-
429420< p > I usually think of this event-raising as a kind of glue - it’s orchestration
430421code. Raising events from your handlers this way makes the flow of messages
431422explicit - you don’t have to look anywhere else in the system to understand
@@ -445,7 +436,6 @@ <h2>Mapping our requirements to our domain</h2>
445436 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> events</ span > < span class ="o "> .</ span > < span class ="n "> add</ span > < span class ="p "> (</ span > < span class ="n "> IssueAssignedToEngineer</ span > < span class ="p "> (</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> id</ span > < span class ="p "> ,</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> assigned_to</ span > < span class ="p "> ,</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> assigned_by</ span > < span class ="p "> ))</ span >
446437</ code > </ pre > </ div >
447438
448-
449439< p > There’s a couple of benefits of doing this: firstly, it keeps our command
450440handler simpler, but secondly it pushes the logic for deciding when to send an
451441event into the model. For example, maybe we don’t always need to raise the
@@ -461,7 +451,6 @@ <h2>Mapping our requirements to our domain</h2>
461451 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> events</ span > < span class ="o "> .</ span > < span class ="n "> add</ span > < span class ="p "> (</ span > < span class ="n "> IssueAssignedToEngineer</ span > < span class ="p "> (</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> id</ span > < span class ="p "> ,</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> assigned_to</ span > < span class ="p "> ,</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> assigned_by</ span > < span class ="p "> ))</ span >
462452</ code > </ pre > </ div >
463453
464-
465454< p > Now we’ll only raise our event if the issue was assigned by another engineer.
466455Cases like this are more like business logic than glue code, so today I’m
467456choosing to put them in my domain model. Updating our unit tests is trivial,
@@ -485,7 +474,6 @@ <h2>Mapping our requirements to our domain</h2>
485474 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> assigned_by</ span > < span class ="p "> )))</ span >
486475</ code > </ pre > </ div >
487476
488-
489477< p > The have_raised function is a custom matcher I wrote that checks the events
490478attribute of our object to see if we raised the correct event. It’s easy to test
491479for the presence of events, because they’re namedtuples, and have value
@@ -540,7 +528,6 @@ <h2>Mapping our requirements to our domain</h2>
540528 < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> publish_events</ span > < span class ="p "> ()</ span >
541529</ code > </ pre > </ div >
542530
543-
544531< p > Okay, we’ve covered a lot of ground here. We’ve discussed why you might want to
545532use domain events, how a message bus actually works in practice, and how we can
546533get events out of our domain and into our subscribers. The newest code sample
0 commit comments