Using annotations in Prooph

One of the things I love about Java is its native, compiler-level support for annotations, a form of syntactic metadata which can be applied to source code but also retain at run-time to influence application behavior. I use them almost daily in my projects.

I do a fair amount of consulting and development on event sourced applications and these usually use Axon, a popular CQRS & event sourcing framework. Recently, Axon version 3 was released, supporting a number of annotations that can turn any POJO (Plain Old Java Object) into an event-sourced aggregate.

The annotations in Axon inspired me to experiment with adding support for similar annotations to prooph, a PHP framework which I occasionally reference in my PHP conference talks and consulting. This experiment is now available online as a PHP package, on GitHub:ย https://github.com/prooph/annotations. It works with the last versions of the core prooph components.

The package, like Axon, introduces a number of annotations which allow you to turn any regular PHP class into an event-sourced aggregate. Unfortunately, annotations are not natively supported in PHP. They are written inside documentation blocks and require an additional parser to get working (in the case of my package, Doctrine Annotations). The following example snippet shows how these annotations are applied:

class TodoItem
{
    /**
     * @AggregateIdentifier
     * @var string
     */
    private $itemId;

    /**
     * TodoItem constructor.
     * @CommandHandler
     * @param PostTodo $command
     */
    public function __construct(PostTodo $command)
    {
        AggregateLifecycle::recordThat(new TodoPosted($command->getItemId()));
    }

    /**
     * @EventHandler
     * @param TodoPosted $event
     */
    public function onTodoPosted(TodoPosted $event)
    {
        $this->itemId = $event->getItemId();
    }
}

@CommandHandler helps to get rid of some of the boilerplate code usually associated with command handlers in prooph (see this example). @EventHandler turns any annotated function into an event listener.

Let me know what you think!

Michiel Rook

Michiel Rook is an experienced, passionate & pragmatic freelance coach, developer & speaker from the Netherlands. He loves helping teams and companies to develop better software and significantly improve their delivery process. When heโ€™s not thinking about continuous deployment, DevOps or event sourcing he enjoys music, cars, sports and movies.

2 thoughts on “Using annotations in Prooph

  • January 2, 2018 at 8:02 am
    Permalink

    Overall love the Axon approach, which removes a layer of command handling boilerplate, so this is absolutely a +1!

    Just don’t abuse constructors and make them private next time. Named constructors FTW! ๐Ÿ˜œ

  • January 2, 2018 at 9:38 am
    Permalink

    Thanks! I’m not really a fan of named constructors and I’d love to have method overloading, but I guess we can’t really have nice things ๐Ÿ˜‰

Leave a Reply

Your email address will not be published. Required fields are marked *