cult3

Creating and Using a Command Bus

Nov 10, 2014

Table of contents:

  1. Domain Driven Design architecture recap
  2. What is the job of the Application Layer?
  3. How do you implement the Application Layer?
  4. What are the differences between Application Services and The Command Bus?
  5. Building the Command Bus
  6. The Command Interface
  7. The Handler Interface
  8. The Container
  9. The Inflector
  10. The CommandBus Implementation
  11. Conclusion

There are three different layers to Domain Driven Design applications, each with their own roles and responsibilities within the application stack.

Over the past couple of weeks we’ve been looking at mainly the Domain and Infrastructure layers of our applications.

Whilst the Domain and Infrastructure layers are important, we are missing one important component of the Domain Driven Design trifecta, The Application Layer.

In today’s tutorial we’re going to be looking at building the Application layer of Cribbb and seeing how each piece has a role in the architecture of the application.

Domain Driven Design architecture recap

The architecture of a Domain Driven Design project is comprised of three main areas. Each areas has it’s own unique role and responsibilities within the bigger context of the entire application. It is very important that the responsibility of a particular layer does not leak out into other aspects of the application.

The Domain layer

The real business logic of the application should be encapsulated with the Domain Layer. This means that any rules or criteria the application requires should sit within the Domain layer and not leak out into the other layers of the application.

The Domain layer is comprised of Entities and Value Objects as well as Domain Events and other objects that capture the business rules of the application.

So far we’ve covered the following sections of the Domain layer:

The Infrastructure Layer

The Infrastructure Layer is made up of all the technical details of how our application is implemented.

For example, most applications require a database and so the code that interacts with the database would sit in the Infrastructure Layer.

Domain Driven applications should rely on interfaces and not implementations. This means we would rely on a Mailer interface, but we would use a MailGunMailer implementation that implements the interface we require.

So far we’ve covered the following sections of the Infrastructure layer:

What is the job of the Application Layer?

The Application Layer of a Domain Driven Design application acts as a public API to the application. The Application layer will accept requests from the outside world and return responses in an appropriate manner.

The Application Layer is important because it acts as an agnostic barrier between the outside world and your application. Your application should not care where a request comes from.

The Application Layer also acts as a conductor by pulling in the services it requires to satisfy a request or send a response. This might mean sending Commands into a Command Bus, or running a query on a Repository.

How do you implement the Application Layer?

I’m by no means an expert in this area of application development, but it seems to me that there are basically two methods for implementing the Application layer.

Application Services

The first method is to use Application Services. An Application Service is basically just a class with methods for the various tasks your application can perform.

For example, you might have the following IdentityApplicationService:

class IdentityApplicationService
{
    /**
     * Register a new user
     *
     * @param string $email
     * @param string $username
     * @param string $password
     * @return User
     */
    public function register($email, $username, $password)
    {
        // register a new user
    }
}

The register() method on this Application Service would accept the raw strings from the request and use the internal RegisterUserService to create a new User object.

The Application Service would be injected with the various services it requires to complete the task. Application Service would generally separated by functional area of the application and would group together related methods.

Command Bus

Alternatively you have the Command Bus approach. A Command Bus accepts a Command object and delegates it to a Command Handler.

For example, you might have a RegisterUserCommand that is sent to the Command Bus and delegated to a RegisterUserHandler.

The RegisterUserHandler would be able to handle the process for registering a new user in the application.

What are the differences between Application Services and The Command Bus?

There are many differences between Application Services and The Command Bus and both have their positives and negatives.

Firstly, Application Services tend to be more complicated than using a Command Bus. This is because grouping together many related tasks means you end up with a large class that requires a number of dependencies and has a lot of responsibility.

Using a Command Bus is far more simpler because each Command has a single Command Handler. Each Handler only needs to be concerned with satisfying a single Command, and so your code ends up much closer to The Single Responsibility Principle.

However on the other hand, using a Command Bus can be more complicated than using an Application Service in some situations. A Command Bus should not return a value after a Command has been handled.

For example, if you were creating a new resource in your application, you would not be returned the id of the new resource so you could redirect the user to it’s view page.

Now arguably, this is probably only going to make using a Command Bus more difficult if you are trying to use a Command Bus for the wrong job. If you face this situation, you should probably use an Application Service.

However testing A Command Bus is more difficult because it’s harder to test code when there is no return value from the method call. I’m still trying to get my head around this one.

When you begin writing The Application Layer of your application, you don’t need to choose either Application Services or a Command Bus. You can very easily use one type of implementation for certain functionality of your application and another for other aspects. It’s about choosing the right tool for the job, and not trying to fit a square peg in a round hole.

Building the Command Bus

I’m going to be using a Command Bus in Cribbb for certain aspects of the Application. So today we’ll look at building out The Command Bus.

As I covered last week in Creating your own Domain Event Dispatcher, you have the option of either using a ready made Command Bus package or rolling your own. Using Open Source packages is a fantastic way of not wasting time by trying to reinvent the wheel.

However as I advocated last week, I do believe that certain components of your application should sit within your walled garden, even if you end up building a generic tool for a generic problem. I think having complete control of the API and future evolution of application critical components is worth the time investment of writing your own code.

The Command Bus infrastructure will be made up of three main components:

  1. Commands are the data objects that are passed into The Command Bus
  2. Handlers deal with accepting a Command and completing the required task
  3. The Command Bus is responsible for mapping Commands to Command Handlers and instantiating the required objects

You will notice that this set up is not that different to implementing Domain Events from last week. The theory is very similar, however the big difference is Commands only have one Handler, whereas Events have many Listeners.

Now that we’ve got the theory down, lets look at building a Command Bus!

The Command Interface

The first thing we need to create is the Command interface:

<?php namespace Cribbb\Application;

interface Command
{
}

The Command interface doesn’t need to have any method definitions because Commands are basically just plain old PHP objects that hold data.

You might be thinking, what’s the point in the interface then? I think there is still a lot of value to implementing interfaces even if the interface does not contain any methods. This is because it makes your code a lot more readable and easier to understand for new developers.

The Handler Interface

Next we need to define a Handler interface:

<?php namespace Cribbb\Application;

interface Handler
{
    /**
     * Handle a Command object
     *
     * @param Command $command
     * @return void
     */
    public function handle(Command $command);
}

Each Handler will require a handle() method that should accept a Command. We don’t really care how the Handler actually handles the command, we only care about telling it what to do.

The Container

The Command Bus will be responsible for instantiating a new Handler instance when given a particular Command. This means the Command Bus needs a way of creating other objects.

If you are familiar with Laravel, you will know about the framework’s very powerful IoC Container. A couple of months I wrote a post on exploring Laravel’s IoC Container.

We can inject an instance of the Laravel’s Container into our Command Bus, but that would mean we have coupled ourselves to Laravel’s implementation.

Instead we can define a Container interface that we can rely on instead. This means we can effectively replace the IoC Container with a different implementation that also satisfies the interface contract:

<?php namespace Cribbb\Application;

interface Container
{
    /**
     * Return a new instance of an object
     *
     * @param string $class
     * @return mixed
     */
    public function make($class);
}

The LaravelContainer implementation looks like this:

<?php namespace Cribbb\Application;

use Illuminate\Container\Container as IoC;

class LaravelContainer implements Container
{
    /**
     * @var Container
     */
    private $container;

    /**
     * Create a new LaravelContainer
     *
     * @param IoC $container
     * @return void
     */
    public function __construct(IoC $container)
    {
        $this->container = $container;
    }

    /**
     * Resolve the class out of the Container
     *
     * @param string $class
     * @return mixed
     */
    public function make($class)
    {
        return $this->container->make($class);
    }
}

To test the LaravelContainer implementation we can attempt to resolve a class out of the Container:

<?php namespace Cribbb\Tests\Application;

use stdClass;
use Illuminate\Container\Container;
use Cribbb\Application\LaravelContainer;

class LaravelContainerTest extends \PHPUnit_Framework_TestCase
{
    /** @var LaravelContainer */
    private $container;

    public function setUp()
    {
        $container = new Container();
        $container->bind("Cat", function () {
            $cat = new stdClass();
            $cat->name = "lolcat";
            return $cat;
        });

        $this->container = new LaravelContainer($container);
    }

    /** @test */
    public function should_make_class_from_container()
    {
        $class = $this->container->make("Cat");

        $this->assertInstanceOf("stdClass", $class);
        $this->assertEquals("lolcat", $class->name);
    }
}

The Inflector

The Command Bus should also be responsible for mapping Commands to Handlers. Instead of lumping this responsibility into the Command Bus, we can instead write a dedicated Inflector that can do the job for us.

As time goes by we might want to change the organisation of our code and so I think it makes sense to create an Inflector interface:

<?php namespace Cribbb\Application;

interface Inflector
{
    /**
     * Find a Handler for a Command
     *
     * @param Command $command
     * @return string
     */
    public function inflect(Command $command);
}

A simple string replace Inflector implementation could be as follows:

<?php namespace Cribbb\Application;

class NameInflector implements Inflector
{
    /**
     * Find a Handler for a Command
     *
     * @param Command $command
     * @return string
     */
    public function inflect(Command $command)
    {
        return str_replace("Command", "Handler", get_class($command));
    }
}

We can test this Inflector implementation with the following tests:

<?php namespace Cribbb\Tests\Application;

use stdClass;
use Cribbb\Stubs\CommandStub;
use Cribbb\Application\NameInflector;

class NameInflectorTest extends \PHPUnit_Framework_TestCase
{
    /** @var Inflector */
    private $inflector;

    public function setUp()
    {
        $this->inflector = new NameInflector();
    }

    /** @test */
    public function should_get_handler_name_from_command()
    {
        $command = new CommandStub(new stdClass());

        $handler = $this->inflector->inflect($command);

        $this->assertEquals("Cribbb\Stubs\HandlerStub", $handler);
    }
}

Shout out to Chris Fidao’s Hexagonal PHP repository for the inspiration of this technique.

The CommandBus Implementation

Finally we have the CommandBus implementation. The Command Bus should be injected with instances of Container and Inflector and it should have an execute() method that accepts a Command:

<?php namespace Cribbb\Application;

class CommandBus
{
    /**
     * @var Container
     */
    private $container;

    /**
     * @var Inflector
     */
    private $inflector;

    /**
     * Create a new CommandBus
     *
     * @param Container $container
     * @return void
     */
    public function __construct(Container $container, Inflector $inflector)
    {
        $this->container = $container;
        $this->inflector = $inflector;
    }

    /**
     * Execute a Command by passing it to a Handler
     *
     * @param Command $command
     * @return void
     */
    public function execute(Command $command)
    {
        $this->handler($command)->handle($command);
    }

    /**
     * Get the Command Handler
     *
     * @return mixed
     */
    private function handler(Command $command)
    {
        $class = $this->inflector->inflect($command);

        return $this->container->make($class);
    }
}

As you can see, the execute() method does not return any value. I’ve also made use of a private method for determining which Handler to use and then resolving it from the Container.

Conclusion

The Application layer of a Domain Driven Design application is the final piece of the puzzle. The Application handles communicating with the outside world by accepting requests and returning responses. By acting as a boundary to the application, the internal code does not care where the request comes from or where it is going.

There are a couple of common approaches to building out the Application layer. Two popular choices are Application Services or using Commands and Command Handlers. Both approaches have positives and negatives and so it is up to you to decide which is right for the task at hand.

Today we created a simple Command Bus implementation. I also mentioned last week, the majority of the time you should be using Open Source components whenever you can. Open Source components are usually stronger, more robust and actively maintained. However sometimes I do think there is a benefit to bringing critical components in-house so you can completely control the interface and the implementation.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.