CQRS, or did you mean CARS?

CQRS, or did you mean CARS?

Everything you would want to discover when you're googling for CQRS for the first time. From general OOP principles to CQRS and Event Sourcing

0cab45c75f109eb044564efbd28af603?s=128

Stijn Vannieuwenhuyse

February 25, 2014
Tweet

Transcript

  1. CQRS DID YOU MEAN CARS?

  2. STIJN VANNIEUWENHUYSE @STIJNVNH ONE AGENCY - AUSY BELGIUM SOFTWARE DEVELOPER

    TDD, DDD, CQRS, ES & PHP
  3. SOME REMARKS I know where I'm heading I don't know

    where I'll arrive I have assumptions about your knowledge I want to know if my assumptions were correct I try to answer every question I want to be stopped when something is not clear I want to be stopped when it has been long enough I want to know if you don't agree I know the examples are over-simplified I want to know if there are mistakes in my slides ;-)
  4. SOFTWARE WHY DO WE WANT SOFTWARE?

  5. VALUE

  6. STATE

  7. BEHAVIOUR

  8. FLEXIBLE

  9. SOFTWARE HOW DO WE BUILD GOOD SOFTWARE?

  10. ABBREVIATIONS FTW! TDD BDD DDD GO4 SOA OOP

  11. OBJECT ORIENTED HOW DO WE BUILD OBJECT ORIENTED SOFTWARE?

  12. SOLID

  13. SRP SINGLE RESPONSIBILITY PRINCIPLE a class should have a single

    responsibility
  14. OCP OPEN-CLOSED PRINCIPLE software should be open for extension, but

    closed for modification
  15. LSP LISKOV SUBSTITUTION PRINCIPLE subtypes should be useable without affecting

    the correctness of the software
  16. ISP INTERFACE SEGREGATION PRINCIPLE many client-specific interfaces are better than

    one general-purpose one
  17. DIP DEPENDENCY INVERSION PRINCIPLE depend upon abstractions, do not depend

    upon concretions
  18. CQS COMMAND QUERY SEPARATION methods should either modify state or

    return state, never both.
  19. ENCAPSULATION TELL, DON'T ASK PRINCIPLE try to use the query

    methods as little as possible
  20. SOFTWARE HOW DO WE BUILD SOFTWARE NOW?

  21. MODEL DB CLIENT user interacts orm persists orm hydrates dto

  22. CQRS COMMAND QUERY RESPONSIBILITY SEGREGATION split up your model in

    separate classes for either returning state or either changing state similar to CQS, but applied to classes design principle
  23. WRITE MODEL DB CLIENT command orm persists orm hydrates dto

    READ MODEL
  24. i n t e r f a c e S

    h o p p i n g C a r t { / / p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ s h o p p i n g C a r t I d ) ; p u b l i c f u n c t i o n a d d I t e m ( I t e m $ i t e m ) ; p u b l i c f u n c t i o n r e m o v e I t e m ( I t e m $ i t e m ) ; p u b l i c f u n c t i o n c h e c k o u t ( ) ; p u b l i c f u n c t i o n g e t I d ( ) ; p u b l i c f u n c t i o n g e t I t e m s ( ) ; p u b l i c f u n c t i o n g e t T o t a l ( ) ; }
  25. i n t e r f a c e S

    h o p p i n g C a r t R e p o s i t o r y { p u b l i c f u n c t i o n f i n d A l l ( ) ; p u b l i c f u n c t i o n f i n d O n e B y I d ( $ s h o p p i n g C a r t I d ) ; p u b l i c f u n c t i o n s a v e ( S h o p p i n g C a r t $ s h o p p i n g C a r t ) ; }
  26. c l a s s S h o p p

    i n g C a r t A p i C o n t r o l l e r { p u b l i c f u n c t i o n a d d I t e m T o S h o p p i n g C a r t ( $ s h o p p i n g C a r t I d , $ i t e m I d ) { $ s h o p p i n g C a r t = $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > f i n d O n B y I d ( $ s h o p p i n g C a r t I d ) ; $ i t e m = $ t h i s - > i t e m R e p o s i t o r y - > f i n d O n e B y I d ( $ i t e m I d ) ; $ s h o p p i n g C a r t - > a d d I t e m ( $ i t e m ) ; $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > s a v e ( $ s h o p p i n g C a r t ) ; } p u b l i c f u n c t i o n g e t S h o p p i n g C a r t I n f o ( $ s h o p p i n g C a r t I d ) { $ s h o p p i n g C a r t = $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > f i n d O n B y I d ( $ s h o p p i n g C a r t I d ) ; r e t u r n j s o n _ e n c o d e ( ( o b j e c t ) [ ' i d ' = > $ s h o p p i n g C a r t - > g e t I d ( ) , ' n u m b e r O f I t e m s ' = > c o u n t ( $ s h o p p i n g C a r t - > g e t I t e m s ( ) ) , ' t o t a l ' = > $ s h o p p i n g C a r t - > g e t T o t a l ( ) ] ) ; } / / . . . }
  27. CQRS SPLIT YOUR MODEL split up your DTOs into read-entities

    and commands make a separate repository for your read-entities you are able to use your entities for write only you are able to use your read-entities for read only
  28. i n t e r f a c e S

    h o p p i n g C a r t { / / p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ s h o p p i n g C a r t I d ) ; p u b l i c f u n c t i o n a d d I t e m ( I t e m $ i t e m ) ; p u b l i c f u n c t i o n r e m o v e I t e m ( I t e m $ i t e m ) ; p u b l i c f u n c t i o n c h e c k o u t ( ) ; }
  29. i n t e r f a c e S

    h o p p i n g C a r t R e p o s i t o r y { p u b l i c f u n c t i o n f i n d O n e B y I d ( $ s h o p p i n g C a r t I d ) ; p u b l i c f u n c t i o n s a v e ( S h o p p i n g C a r t $ s h o p p i n g C a r t ) ; }
  30. c l a s s A d d I t

    e m T o S h o p p i n g C a r t i m p l e m e n t s C o m m a n d { p r i v a t e $ s h o p p i n g C a r t I d ; p r i v a t e $ i t e m I d ; p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ s h o p p i n g C a r t I d , $ i t e m I d ) { $ t h i s - > s h o p p i n g C a r t I d = $ s h o p p i n g C a r t I d ; $ t h i s - > i t e m I d = $ i t e m I d ; } p u b l i c f u n c t i o n g e t S h o p p i n g C a r t I d ( ) { r e t u r n $ t h i s - > s h o p p i n g C a r t I d ; } p u b l i c f u n c t i o n g e t I t e m I d ( ) { r e t u r n $ t h i s - > i t e m I d ; } }
  31. COMMANDS message user intention verb, imperative command handler can be

    refused (ACK-NACK)
  32. c l a s s A d d I t

    e m T o S h o p p i n g C a r t C o m m a n d H a n d l e r i m p l e m e n t s C o m m a n d H a n d l e r { p u b l i c f u n c t i o n h a n d l e ( A d d I t e m T o S h o p p i n g C a r t $ c o m m a n d ) { $ s h o p p i n g C a r t = $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > f i n d O n B y I d ( $ c o m m a n d - > g e t S h o p p i n g C a r t I d ( ) ) ; $ i t e m = $ t h i s - > i t e m R e p o s i t o r y - > f i n d O n e B y I d ( $ c o m m a n d - > g e t I t e m I d ( ) ) ; $ s h o p p i n g C a r t - > a d d I t e m ( $ i t e m ) ; $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > s a v e ( $ s h o p p i n g C a r t ) ; } / / . . . }
  33. COMMANDS explicit user intention task based user interface Ubiquitous language

  34. QUERIES read model DTOs read-entities database views

  35. i n t e r f a c e S

    h o p p i n g C a r t I n f o { / / p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ s h o p p i n g C a r t I d , $ n u m b e r O f I t e m s , $ t o t a l ) ; p u b l i c f u n c t i o n g e t I d ( ) ; p u b l i c f u n c t i o n g e t N u m b e r O f I t e m s ( ) ; p u b l i c f u n c t i o n g e t T o t a l ( ) ; p u b l i c f u n c t i o n j s o n S e r i a l i z e ( ) ; }
  36. i n t e r f a c e S

    h o p p i n g C a r t I n f o R e p o s i t o r y { p u b l i c f u n c t i o n f i n d A l l ( ) ; p u b l i c f u n c t i o n f i n d O n e B y I d ( $ s h o p p i n g C a r t I d ) ; }
  37. c l a s s S q l S h

    o p p i n g C a r t I n f o R e p o s i t o r y i m p l e m e n t s S h o p p i n g C a r t I n f o R e p o s i t o r y { / / . . . p u b l i c f u n c t i o n f i n d O n e B y I d ( $ s h o p p i n g C a r t I d ) { $ s q l = ' S E L E C T . . . ' ; / / s o m e c o m p l e x s q l s t a t e m e n t $ r e s u l t = $ t h i s - > d a t a b a s e - > f e t c h ( $ s q l ) ; r e t u r n n e w S h o p p i n g C a r t I n f o ( $ r e s u l t - > i d , $ r e s u l t - > n u m b e r O f I t e m s , $ r e s u l t - > t o t a l ) ; } }
  38. c l a s s S h o p p

    i n g C a r t A p i C o n t r o l l e r { / / . . . p u b l i c f u n c t i o n g e t S h o p p i n g C a r t I n f o ( $ s h o p p i n g C a r t I d ) { r e t u r n j s o n _ e n c o d e ( $ t h i s - > s h o p p i n g C a r t I n f o R e p o s i t o r y - > f i n d O n B y I d ( $ s h o p p i n g C a r t I d ) ) ; } }
  39. c l a s s C o m m a

    n d A p i C o n t r o l l e r { / / . . . p u b l i c f u n c t i o n h a n d l e ( $ c o m m a n d ) { $ c o m m a n d = $ t h i s - > c o m m a n d D e s e r i a l i z e r - > d e s e r i a l i z e ( $ c o m m a n d ) ; $ t h i s - > c o m m a n d D i s p a t c h e r - > d i s p a t c h ( $ c o m m a n d ) ; } }
  40. DESIGN move logic to your model instead of application layer

    make domain language explicit in your code
  41. PROGRAMMER OPTIMIZATION let senior developers work the write side let

    junior developers work the read side let front-end developers work the client side or not...
  42. SOFTWARE HOW DO WE BUILD SOFTWARE NOW?

  43. WRITE MODEL DB CLIENT command orm persists sql resultset dto

    READ MODEL COMMAND HANDLER DTO BUILDER
  44. CQRS COMMAND QUERY RESPONSIBILITY SEGREGATION split up your persistence in

    separate parts for either returning state or either changing state architectural choice
  45. WRITE MODEL DB CLIENT command orm persists sql resultset dto

    READ MODEL COMMAND HANDLER DTO BUILDER DB
  46. WRITE MODEL DB CLIENT command orm persists sql resultset dto

    READ MODEL COMMAND HANDLER DTO BUILDER DB event
  47. EVENT message history, a change in the system sentence, passed

    tense publish-subscribe is the truth
  48. c l a s s I t e m W

    a s A d d e d T o S h o p p i n g C a r t i m p l e m e n t s D o m a i n E v e n t { p r i v a t e $ s h o p p i n g C a r t I d ; p r i v a t e $ i t e m I d ; p r i v a t e $ p r i c e ; p u b l i c f u n c t i o n _ _ c o n s t r u c t ( $ s h o p p i n g C a r t I d , $ i t e m I d , $ p r i c e ) { $ t h i s - > s h o p p i n g C a r t I d = $ s h o p p i n g C a r t I d ; $ t h i s - > i t e m I d = $ i t e m I d ; $ t h i s - > p r i c e = $ p r i c e ; } p u b l i c f u n c t i o n g e t S h o p p i n g C a r t I d ( ) { r e t u r n $ t h i s - > s h o p p i n g C a r t I d ; } p u b l i c f u n c t i o n g e t I t e m I d ( ) { r e t u r n $ t h i s - > i t e m I d ; } p u b l i c f u n c t i o n g e t P r i c e ( ) { r e t u r n $ t h i s - > p r i c e ; } }
  49. COMMAND HANDLER turns a command into events uses an aggregate

    to protect invariants publishes events
  50. c l a s s A d d I t

    e m T o S h o p p i n g C a r t C o m m a n d H a n d l e r i m p l e m e n t s C o m m a n d H a n d l e r { p u b l i c f u n c t i o n h a n d l e ( A d d I t e m T o S h o p p i n g C a r t $ c o m m a n d ) { $ s h o p p i n g C a r t = $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > f i n d O n B y I d ( $ c o m m a n d - > g e t S h o p p i n g C a r t I d ( ) ) ; $ i t e m = $ t h i s - > i t e m R e p o s i t o r y - > f i n d O n e B y I d ( $ c o m m a n d - > g e t I t e m I d ( ) ) ; $ s h o p p i n g C a r t - > a d d I t e m ( $ i t e m , $ t h i s - > e v e n t P u b l i s h e r ) ; $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > s a v e ( $ s h o p p i n g C a r t ) ; } / / . . . }
  51. c l a s s S h o p p

    i n g C a r t i m p l e m e n t s A g g r e g a t e R o o t { p u b l i c f u n c t i o n a d d I t e m ( I t e m $ i t e m , E v e n t P u b l i s h e r $ e v e n t P u b l i s h e r ) { $ t h i s - > i t e m s [ ] = $ i t e m ; $ e v e n t P u b l i s h e r - > p u b l i s h ( n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( $ t h i s - > g e t I d ( ) , $ i t e m - > g e t I d ( ) , $ i t e m - > g e t P r i c e ( ) ) ) ; } / / . . . }
  52. PROJECTOR turns events into state produces read-models subscribes to events

  53. c l a s s S h o p p

    i n g C a r t I n f o P r o j e c t o r i m p l e m e n t s P r o j e c t o r { p u b l i c f u n c t i o n p r o j e c t ( I t e m W a s A d d e d T o S h o p p i n g C a r t $ e v e n t ) { $ s h o p p i n g C a r t I n f o = $ t h i s - > s h o p p i n g C a r t I n f o R e p o s i t o r y - > f i n d O n B y I d ( $ e v e n t - > g e t S h o p p i n g C a r t I d ( ) ) ; $ s h o p p i n g C a r t I n f o - > u p d a t e ( 1 , $ e v e n t - > g e t P r i c e ( ) ) ; $ t h i s - > s h o p p i n g C a r t I n f o R e p o s i t o r y - > s a v e ( $ s h o p p i n g C a r t I n f o ) ; } / / . . . }
  54. PERFORMANCE reading goes faster writing goes slower

  55. DESIGN make domain language explicit in your code decouple components

  56. READ MODEL READ MODEL WRITE MODEL DB CLIENT command orm

    persists dto READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB
  57. INFRASTRUCTURE OPTIMIZATION choose other infrastructure that suits better for the

    problem at hand
  58. BTW EVENTSTORMING workshop format to detect commands & events of

    the business with domain experts introduced by Alberto Brandolini
  59. SOFTWARE HOW DO WE BUILD SOFTWARE NOW?

  60. READ MODEL READ MODEL WRITE MODEL DB CLIENT command orm

    persists dto READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB
  61. EVENT SOURCING all events produce the current state all events

    of an aggregate produce the current state of the aggregate use events as persistence instead of state
  62. READ MODEL READ MODEL WRITE MODEL ES CLIENT command event

    dto READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB
  63. CHANGING STATE an aggregate records its own new events newly

    recorded events are appended to an event store
  64. c l a s s S h o p p

    i n g C a r t { p u b l i c f u n c t i o n a d d I t e m ( $ i t e m I d , $ p r i c e ) { $ t h i s - > c h a n g e s [ ] = n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( $ t h i s - > s h o p p i n g C a r t I d , $ i t e m I d , $ p r i c e ) ; } / / . . . }
  65. c l a s s A d d I t

    e m T o S h o p p i n g C a r t C o m m a n d H a n d l e r i m p l e m e n t s C o m m a n d H a n d l e r { p u b l i c f u n c t i o n h a n d l e ( A d d I t e m T o S h o p p i n g C a r t $ c o m m a n d ) { $ s h o p p i n g C a r t = $ t h i s - > s h o p p i n g C a r t R e p o s i t o r y - > f i n d O n B y I d ( $ c o m m a n d - > g e t S h o p p i n g C a r t I d ( ) ) ; $ i t e m = $ t h i s - > i t e m R e p o s i t o r y - > f i n d O n e B y I d ( $ c o m m a n d - > g e t I t e m I d ( ) ) ; $ s h o p p i n g C a r t - > a d d I t e m ( $ i t e m - > g e t I d ( ) , $ i t e m - > g e t P r i c e ( ) ) ; $ t h i s - > e v e n t S t o r e - > c o m m i t ( $ s h o p p i n g C a r t - > g e t C h a n g e s ( ) ) ; } / / . . . }
  66. c l a s s E v e n t

    S t o r e S h o p p i n g C a r t R e p o s i t o r y i m p l e m e n t s S h o p p i n g C a r t R e p o s i t o r y { p u b l i c f u n c t i o n f i n d O n B y I d ( $ s h o p p i n g C a r t I d ) { $ s h o p p i n g C a r t E v e n t s = $ t h i s - > e v e n t S t o r e - > f i n d F o r ( $ s h o p p i n g C a r t I d ) ; r e t u r n S h o p p i n g C a r t : : r e c o n s t i t u t e ( $ s h o p p i n g C a r t I d , $ s h o p p i n g C a r t E v e n t s ) ; } / / . . . }
  67. INVARIANTS an aggregate needs history to protect invariants apply all

    events to the aggregate to rebuild relevant state
  68. c l a s s S h o p p

    i n g C a r t i m p l e m e n t s A g g r e g a t e R o o t { p u b l i c s t a t i c f u n c t i o n r e c o n s t i t u t e ( $ s h o p p i n g C a r t I d , a r r a y $ s h o p p i n g C a r t E v e n t s ) { $ s h o p p i n g C a r t = n e w s e l f ( $ s h o p p i n g C a r t I d ) ; f o r e a c h ( $ s h o p p i n g C a r t E v e n t s a s $ e v e n t ) { $ s h o p p i n g C a r t - > a p p l y ( $ e v e n t ) ; } r e t u r n $ s h o p p i n g C a r t ; } p r i v a t e f u n c t i o n a p p l y ( D o m a i n E v e n t $ e v e n t ) { / / f o r w a r d t o s p e c i f i c a p p l y - m e t h o d } p r i v a t e f u n c t i o n a p p l y I t e m W a s A d d e d T o S h o p p i n g C a r t ( I t e m W a s A d d e d T o S h o p p i n g C a r t $ e v e n t ) { } / / . . . }
  69. c l a s s S h o p p

    i n g C a r t i m p l e m e n t s A g g r e g a t e R o o t { p r i v a t e $ n u m b e r O f I t e m s = 0 ; p u b l i c f u n c t i o n a d d I t e m ( $ i t e m I d , $ p r i c e ) { i f ( $ t h i s - > n u m b e r O f I t e m s > 2 ) { t h r o w n e w E x c e p t i o n ( ' Y o u c a n o n l y h a v e 3 i t e m s i n y o u r s h o p p i n g c a r t ' ) ; } $ e v e n t = n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( $ t h i s - > s h o p p i n g C a r t I d , $ i t e m I d , $ p r i c e ) ; $ t h i s - > c h a n g e s [ ] = $ e v e n t ; $ t h i s - > a p p l y ( $ e v e n t ) ; } p r i v a t e f u n c t i o n a p p l y I t e m W a s A d d e d T o S h o p p i n g C a r t ( I t e m W a s A d d e d T o S h o p p i n g C a r t $ e v e n t ) { $ t h i s - > n u m b e r O f I t e m s + + ; } }
  70. TESTABILITY given a history, when I act upon the system,

    then something should have changed given certain events, when I issue a command, then events should have happened given a history, how is it represented given certain events, then a certain state should be present
  71. c l a s s A d d I t

    e m T o S h o p p i n g C a r t C o m m a n d H a n d l e r T e s t e x t e n d s T e s t C a s e { / * * @ t e s t * / p u b l i c f u n c t i o n s h o u l d _ r e s u l t _ i n t o _ a n _ I t e m W a s A d d e d T o S h o p p i n g C a r t _ e v e n t ( ) { $ t h i s - > s c e n a r i o - > g i v e n ( n e w S h o p p i n g C a r t W a s C r e a t e d ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > w h e n ( n e w A d d I t e m T o S h o p p i n g C a r t ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > t h e n ( n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( / * . . . * / ) ) ; } / * * @ t e s t * / p u b l i c f u n c t i o n s h o u l d _ t h r o w _ w h e n _ t r y i n g _ t o _ a d d _ m o r e _ t h e n _ t h r e e _ i t e m s ( ) { $ t h i s - > s c e n a r i o - > g i v e n ( n e w S h o p p i n g C a r t W a s C r e a t e d ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > g i v e n ( n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > g i v e n ( n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > g i v e n ( n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > w h e n ( n e w A d d I t e m T o S h o p p i n g C a r t ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > t h e n ( n e w E x c e p t i o n ( / * . . . * / ) ) ; } p u b l i c f u n c t i o n s e t U p ( ) { $ t h i s - > s c e n a r i o = n e w S c e n a r i o ( / * . . . * / ) ; } p u b l i c f u n c t i o n t e a r D o w n ( ) { $ t h i s - > s c e n a r i o - > v e r i f y ( ) ;
  72. } }

  73. c l a s s S h o p p

    i n g C a r t I n f o P r o j e c t o r T e s t e x t e n d s T e s t C a s e { / * * @ t e s t * / p u b l i c f u n c t i o n s h o u l d _ p r o j e c t _ a n _ I t e m W a s A d d e d T o S h o p p i n g C a r t _ e v e n t ( ) { $ t h i s - > s c e n a r i o - > g i v e n ( n e w S h o p p i n g C a r t W a s C r e a t e d ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > g i v e n ( n e w I t e m W a s A d d e d T o S h o p p i n g C a r t ( / * . . . * / ) ) ; $ t h i s - > s c e n a r i o - > t h e n ( n e w S h o p p i n g C a r t I n f o ( / * . . * / ) ) ; } / / . . . }
  74. IMMUTABILITY an event store is append only, no database migrations

    needed messages are immutable, event versioning is needed tests don't need adaptation
  75. TEMPORAL QUERIES use read-models to search for certain behaviour over

    time all history is present
  76. CHANGING REQUIREMENTS read-models are temporary, you can throw them away

    don't change read-models, just make a new one add commands and events as needed
  77. SOFTWARE HOW DO WE BUILD SOFTWARE NOW?

  78. READ MODEL READ MODEL WRITE MODEL ES CLIENT command event

    dto READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB
  79. MESSAGES enables messaging enables asynchronous messaging

  80. COMMAND BUS receive commands dispatch commands to correct command handler

    keep track of the command state
  81. EVENT QUEUE receive events publish events to correct event listeners

  82. READ MODEL READ MODEL WRITE MODEL ES CLIENT command event

    dto READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB MQ
  83. INFRASTRUCTURE OPTIMIZATION

  84. READ MODEL READ MODEL WRITE MODEL ES CLIENT command event

    query READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB MQ
  85. EVENTUAL CONSISTENCY clients get immediate ACK-NACK projectors receive events asynchronously

    read-models are not always up to date read-models are always valid
  86. SOFTWARE HOW DO WE BUILD SOFTWARE NOW?

  87. READ MODEL READ MODEL WRITE MODEL ES CLIENT command event

    dto READ MODEL COMMAND HANDLER DTO BUILDER RDB event KVS DDB MQ
  88. RESPONSIBILITIES

  89. WRITE MODEL TURNS A COMMAND INTO EVENTS

  90. READ MODEL TURNS EVENTS INTO STATE

  91. USER TURNS STATE INTO A COMMAND STATE IS A REPRESENTATION

    OF EVENTS
  92. PROCESS TURNS EVENTS INTO A COMMAND

  93. SUMMARY

  94. CQRS COMMAND QUERY RESPONSIBILITY SEGREGATION Single Responsiblity Principle applied on

    class level Single Responsiblity Principle applied on architectural level not an architecture not a framework not a library not event sourcing
  95. ES EVENT SOURCING use events as persistence

  96. CQRS+ES THEY WORK BETTER TOGETHER

  97. BENEFITS components are easy testability programmer optimization infrastructure optimization performance

    optimization immutability temporal queries changing requirements
  98. PITFALLS eventual consistency possible infrastructural chaos boiler plate code immutability

  99. QUESTIONS?

  100. USEFULL RESOURCES @gregyoung - CQRS guru @ericevans0 - DDD guru

    @martinfowler - EAA guru @mathiasverraes - DDD & PHP guru @ziobrando - DDD & eventstorming guru @DDDBE - DDD & CQRS gurus DDD/CQRS - https://groups.google.com/forum/#!forum/dddcqrs DDDinPHP - https://groups.google.com/forum/#!forum/dddinphp
  101. THANK YOU PLEASE GIVE ME FEEDBACK http://joind.in/10777