Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CQRS and Event Sourcing

CQRS and Event Sourcing

CQRS and Event Sourcing are becoming buzzwords nowadays. This presentation tries to clarify both concepts and present a simple example application, written with those powerful architectures

Christian

June 12, 2014
Tweet

More Decks by Christian

Other Decks in Programming

Transcript

  1. CQRS
    EVENT SOURCING

    View Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. Christian Soronellas
    Web Enthusiast
    @theUniC
    theUniC

    View Slide

  6. View Slide

  7. View Slide

  8. Exploration of concepts (CQRS and ES)
    Practical use case
    Conclusions

    View Slide

  9. #phpbcn
    https://github.com/theUniC/blog-cqrs

    View Slide

  10. ¿What is CQRS?

    View Slide

  11. It’s an architectural pattern

    View Slide

  12. Asking a question
    should not change the answer

    View Slide

  13. Methods that return state information should
    not trigger side effects

    View Slide

  14. !
    namespace An\Awesome\Namespace;
    !
    class AnAmazingService
    {
    /** @var An\Awesome\Dependency */
    private $aDependency;
    !
    public function getDependency()
    {
    if (null === $this->aDependency) {
    $this->aDependency = new \An\Awesome\Dependency();
    }
    !
    return $this->aDependency;
    }
    !
    public function anIncredibleAction()
    {
    $aDependency = $this->getDependency();
    $aDependency->performSomethingNeeded();
    // ...
    }
    }

    View Slide

  15. !
    namespace An\Awesome\Namespace;
    !
    class AnAmazingService
    {
    /** @var An\Awesome\Dependency */
    private $aDependency;
    !
    public function getDependency()
    {
    if (null === $this->aDependency) {
    $this->aDependency = new \An\Awesome\Dependency();
    }
    !
    return $this->aDependency;
    }
    !
    public function anIncredibleAction()
    {
    $aDependency = $this->aDependency;
    $aDependency->performSomethingNeeded();
    // ...
    }
    }

    View Slide

  16. CQRS challenges the assumption that
    reading and writing are supposed
    to share the same abstractions

    View Slide

  17. !
    namespace AcmeShop\Billing\DomainModel\Order;
    !
    interface OrderRepository
    {
    /** return Order */
    public function get(OrderId $anId);
    }

    View Slide

  18. !
    namespace AcmeShop\Billing\DomainModel\Order;
    !
    interface OrderRepository
    {
    /** @return Order */
    public function get(OrderId $anId);
    !
    /** @return Order[] */
    public function getByUser(UserId $aUserId);
    }

    View Slide

  19. !
    namespace AcmeShop\Billing\DomainModel\Order;
    !
    interface OrderRepository
    {
    /** @return Order */
    public function get(OrderId $anId);
    !
    /** @return Order[] */
    public function byUser(UserId $aUserId);
    !
    /** @return OrderWithAge[] */
    public function allGroupedByAge();
    }

    View Slide

  20. !
    namespace AcmeShop\Billing\DomainModel\Order;
    !
    interface OrderRepository
    {
    /** @return Order */
    public function get(OrderId $anId);
    !
    /** @return Order[] */
    public function byUser(UserId $aUserId);
    !
    /** @return OrderWithAge[] */
    public function allGroupedByAge();
    !
    /** @return OrderWithCarrier[] */
    public function allGroupedByCarrier();
    }

    View Slide

  21. Command
    sends
    Command Handler
    is handled by
    Write
    Model
    uses
    Event Subscriber
    triggers
    writes
    reads from
    Read
    Model
    queries
    User Interface
    synchronizes with
    returns

    View Slide

  22. Command
    sends
    Command Handler
    is handled by
    Write
    Model
    uses
    Event Subscriber
    triggers
    writes
    reads from
    Read
    Model
    queries
    Eventual Consistency™
    User Interface
    synchronizes with
    returns

    View Slide

  23. Write
    Model
    Event
    Event
    Event
    Event

    View Slide

  24. Events are fundamental part in DDD

    View Slide

  25. We can express the system state as a sequence !
    of events that have occurred

    View Slide

  26. View Slide

  27. POST
    COMMENT
    has many
    belongs to
    AUTHOR
    is written by an
    writes many

    View Slide

  28. [
    {
    "type":"PostWasCreated",
    "created_at": "2014-06-11 18:00:00",
    "data":"{'post_id': 1, 'title': '...', 'content': '...'}"
    }
    ]

    View Slide

  29. [
    {
    "type":"PostWasCreated",
    "created_at": "2014-06-11 18:00:15",
    "data": "{'post_id': 1, 'title': '...', 'content': '...'}"
    },
    {
    "type": "PostWasPublished",
    "created_at": "2014-06-11 18:05:35",
    "data": "{'post_id': 1}"
    }
    ]

    View Slide

  30. [
    {
    "type":"PostWasCreated",
    "created_at": "2014-06-11 18:00:15",
    "data": "{'post_id': 1, 'title': '...', 'content': '...'}"
    },
    {
    "type": "PostWasPublished",
    "created_at": "2014-06-11 18:05:35",
    "data": "{'post_id': 1}"
    },
    {
    "type": "CommentWasCreated",
    "created_at": "2014-06-11 18:15:20",
    "data": "{'post_id': 1, 'comment_id': 1, 'comment': '...'}"
    }
    ]

    View Slide

  31. Event
    Event
    Event
    Event Store™

    View Slide

  32. PostWasCreated
    CommentWasAdded
    PostWasPublished
    Event Store™

    View Slide

  33. Event Sourcing

    View Slide

  34. Practical use case

    View Slide

  35. Conclusions

    View Slide

  36. CQRS and ES combined provide a simple solution
    for complex problems

    View Slide

  37. CQRS allow reads and writes to scale independently

    View Slide

  38. Event Sourcing allow to perform a more efficient and more
    exhaustive debugging

    View Slide

  39. Event Sourcing grants not to be tightly coupled with any
    structure nor any implementation

    View Slide

  40. They’re not the silver bullet
    Use it wisely

    View Slide

  41. ¡Thanks!

    View Slide