Sunday, March 23, 2014

Quick and Dirty Command Handlers, Event Handlers, Wiring it Up

In my last post, I talked about a "quick and dirty" way to create a command bus in F#. In this post, we're going to look at a simple set of command handlers to plug into said bus and some event handlers.

Before I jump right in, let's define what we're looking for. I want to use NEventStore for my event bus (comes with some nice features that make getting up and running much faster). Feel free to plug in whatever event store you might feel like. Creating (an extremely basic) event store isn't too terribly hard, but I am not going to cover it in this post. So, without dragging this out too much more, let's create a function that wraps up the creation of NEventStore.

Serializer

NEventStore needs a serializer. It comes with a few baked in, but I have grown fond of FsPickler. It is really fast and convenient since we're using F#. Here's a quick little helper to create our serializer on demand.

Dispatcher

NEventStore also accepts a dispatcher (the thing that is given the events as they come in). Here is where we're going to accept (for now) our event handlers. If needed, as the documentation suggests, we could fire these events off onto a bus like NServiceBus or Mass Transit. All we're going to do (again, for now) is create a function that will return a dispatcher that passes each event to our event handlers. An event handler is just a function that takes a Guid (the entity's id) and a list (ResizeArray) of events.

Create the Event Store

And, finally, we need to create the event store. There is nothing fancy here, it is pretty much just like the example documentation, just using our serializer and dispatcher. It will also use SQL Server as the backing store along with storing the streams in memory.

So, now that we have an event stream, we can push it into our command handlers and extend our setup function from the last post. We're going to change our command handler function to take in bus. We can simply map the original functions and "apply" the event bus, and then pass the resulting functions into the original "createCommandRouter" function.

A simple little domain

Let's take a look at a silly example of a domain, a counter. The counter can be incremented and decremented and that's about it. Since this is all in F#, we'll use a record to define an entity's state and discriminated union to describe the commands and events. This is a pretty common theme if you go hunting around the internet and it has worked out very well for my projects. Our entities will consist of a state, an apply function, and a handle function. (Lev Gorodinski has a really good write-up on this approach and was the basis for my personal "Ah-ha!" moment.)

Now we just need to wire-up our command handler to use the apply and handle functions. Please keep in mind that this is a "Quick and Dirty" solution to get us going and exploring our domain and wiring things up. You will likely need to a function that the handler can call if it encounters and exception and will probably need to rework the domain to return multiple events from commands and then make the appropriate changes in the command handler to handle that. (Simple, really, but too much noise for this post. I will explore these things in a later post.)

Event handlers are just as simple. They can be used to respond to events from your domain and do things like update projections that feed the application. Our "q 'n d" event handler looks something like this:

The DomainStartup

Putting this together, we now get our new domain startup.

This post is already getting long so I will end it here. Have any feedback or questions, please leave them in the comments or hit me up on Twitter. I'd love to hear how you get started quickly on projects to feel productive without building too much cruft.

No comments:

Post a Comment