@@ -145,7 +145,6 @@ <h2>Mapping our requirements to our domain</h2>
145
145
< 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 >
146
146
</ code > </ pre > </ div >
147
147
148
-
149
148
< p > We’re introducing a new concept - Issues now have a state, and a newly reported
150
149
issue begins in the AwaitingTriage state. We can quickly add a command and
151
150
handler that allows us to triage an issue.</ p >
@@ -161,7 +160,6 @@ <h2>Mapping our requirements to our domain</h2>
161
160
< span class ="n "> uow</ span > < span class ="o "> .</ span > < span class ="n "> commit</ span > < span class ="p "> ()</ span >
162
161
</ code > </ pre > </ div >
163
162
164
-
165
163
< p > Triaging an issue, for now, is a matter of selecting a category and priority.
166
164
We’ll use a free string for category, and an enumeration for Priority. Once an
167
165
issue is triaged, it enters the AwaitingAssignment state. At some point we’ll
@@ -180,7 +178,6 @@ <h2>Mapping our requirements to our domain</h2>
180
178
< span class ="n "> uow</ span > < span class ="o "> .</ span > < span class ="n "> commit</ span > < span class ="p "> ()</ span >
181
179
</ code > </ pre > </ div >
182
180
183
-
184
181
< p > At this point, the handlers are becoming a little boring. As I said way back in
185
182
the first part [https://io.made.com/blog/introducing-command-handler/], commands
186
183
handlers 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>
225
222
< 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 >
226
223
</ code > </ pre > </ div >
227
224
228
-
229
225
< p > Something here feels wrong, right? Our command-handler now has two very distinct
230
226
responsibilities. Back at the beginning of this series we said we would stick
231
227
with three principles:</ p >
@@ -290,7 +286,6 @@ <h2>Mapping our requirements to our domain</h2>
290
286
< 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 >
291
287
</ code > </ pre > </ div >
292
288
293
-
294
289
< p > We don’t really need a unit of work here, because we’re not making any
295
290
persistent changes to the Issue state, so what if we use a view builder instead?</ p >
296
291
< 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>
312
307
< 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 >
313
308
</ code > </ pre > </ div >
314
309
315
-
316
310
< p > That seems better, but how should we invoke our new handler? Building a new
317
311
command and handler from inside our AssignIssueHandler also sounds like a
318
312
violation 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>
386
380
< 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 >
387
381
</ code > </ pre > </ div >
388
382
389
-
390
383
< p > Here we have a bare-bones implementation of a message bus. It doesn’t do
391
384
anything fancy, but it will do the job for now. In a production system, the
392
385
message 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>
404
397
< 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 >
405
398
</ code > </ pre > </ div >
406
399
407
-
408
400
< p > Not much has changed here - we’re still building our command in the Flask
409
401
adapter, but now we’re passing it into a bus instead of directly constructing a
410
402
handler 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>
425
417
< span class ="n "> cmd</ span > < span class ="o "> .</ span > < span class ="n "> assigned_by</ span > < span class ="p "> ))</ span >
426
418
</ code > </ pre > </ div >
427
419
428
-
429
420
< p > I usually think of this event-raising as a kind of glue - it’s orchestration
430
421
code. Raising events from your handlers this way makes the flow of messages
431
422
explicit - 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>
445
436
< 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 >
446
437
</ code > </ pre > </ div >
447
438
448
-
449
439
< p > There’s a couple of benefits of doing this: firstly, it keeps our command
450
440
handler simpler, but secondly it pushes the logic for deciding when to send an
451
441
event 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>
461
451
< 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 >
462
452
</ code > </ pre > </ div >
463
453
464
-
465
454
< p > Now we’ll only raise our event if the issue was assigned by another engineer.
466
455
Cases like this are more like business logic than glue code, so today I’m
467
456
choosing 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>
485
474
< span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> assigned_by</ span > < span class ="p "> )))</ span >
486
475
</ code > </ pre > </ div >
487
476
488
-
489
477
< p > The have_raised function is a custom matcher I wrote that checks the events
490
478
attribute of our object to see if we raised the correct event. It’s easy to test
491
479
for the presence of events, because they’re namedtuples, and have value
@@ -540,7 +528,6 @@ <h2>Mapping our requirements to our domain</h2>
540
528
< span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> publish_events</ span > < span class ="p "> ()</ span >
541
529
</ code > </ pre > </ div >
542
530
543
-
544
531
< p > Okay, we’ve covered a lot of ground here. We’ve discussed why you might want to
545
532
use domain events, how a message bus actually works in practice, and how we can
546
533
get events out of our domain and into our subscribers. The newest code sample
0 commit comments