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

When Microservices Meet Event Sourcing

When Microservices Meet Event Sourcing

Presented at:
* ThoughtWorks Tech Talks NYC Meetup on May 2017
* Developer Week Conference NYC on Jun 2017

Vinicius Gomes

May 11, 2017
Tweet

More Decks by Vinicius Gomes

Other Decks in Programming

Transcript

  1. WHEN
    MICROSERVICES
    MEET
    EVENT SOURCING
    Vinicius Gomes
    1

    View Slide

  2. VINICIUS GOMES
    Software developer at ThoughtWorks
    vvgomes.com/blog
    twitter.com/vvgomes
    2

    View Slide

  3. AGENDA
    The Traditional Approach
    Introduction to Event Sourcing
    CQRS
    Demo
    Summary
    3

    View Slide

  4. THE TRADITIONAL
    APPROACH
    4

    View Slide

  5. EXAMPLE
    Online Restaurant
    5

    View Slide

  6. ONLINE RESTAURANT
    Data Model
    6

    View Slide

  7. ONLINE RESTAURANT
    Services
    7

    View Slide

  8. Restaurant
    ONLINE RESTAURANT
    8
    POST
    GET
    I want to
    open an order!
    200 ✔

    View Slide

  9. Restaurant
    ONLINE RESTAURANT
    9
    POST
    GET
    I want to
    add an item to
    my order!
    200 ✔

    View Slide

  10. THE TRADITIONAL APPROACH
    • Simple to implement
    • Technology agnostic
    10
    GET
    POST
    PUT
    DELETE

    View Slide

  11. CHALLENGES
    11

    View Slide

  12. CHALLENGES
    Coupling
    12

    View Slide

  13. CHALLENGES
    Coupling
    Resilience
    13
    Restaurant
    POST
    GET
    I want to add an item
    to my order!
    503

    View Slide

  14. CHALLENGES
    Coupling
    Resilience
    Response time
    14

    View Slide

  15. CHALLENGES
    Coupling
    Resilience
    Response time
    User intent
    15
    POST /orders/8659a0d6/items/
    Add item to order

    View Slide

  16. CHALLENGES
    Coupling
    Resilience
    Response time
    User intent
    Current / mutable state
    16
    {
    "id": “6a208c41…”,
    "status": "OPEN",
    "items": [
    {
    "id": “be596c8e…”,
    "quantity": 1
    },
    {
    "id": “5d09509c…”,
    "quantity": 2
    },
    {
    "id": “cc52d1b6…”,
    "quantity": 1
    }
    ]
    }

    View Slide

  17. EVENT SOURCING
    17

    View Slide

  18. EVENT SOURCING
    18

    View Slide

  19. DOMAIN EVENTS
    19
    {
    "payload": {
    "orderId": “be596c8e…”,
    "itemId": “5d09509c…”,
    "quantity": 1
    },
    "payloadType": “com.restaurant.ItemAddedToOrderEvent”,
    "timestamp": “2017-03-25 08:48:51 -03:00”,
    "revision": “2”,
    "aggregateId": “6a208c41…”
    }
    Model the past
    Immutable
    Permanent

    View Slide

  20. EVENT STORE
    Append only
    Sequential
    Long-lived
    20

    View Slide

  21. AGGREGATES
    21
    state = reduce(handle, {}, events)
    Reducer function
    Reducing events into state

    View Slide

  22. AGGREGATES
    Example
    22
    { }

    View Slide

  23. AGGREGATES
    Example
    23
    payload: {
    id: “42”
    }
    {
    "id": “42”,
    "status": "OPEN",
    "items": [ ]
    }

    View Slide

  24. AGGREGATES
    Example
    24
    {
    "id": “42”,
    "status": "OPEN",
    "items": [
    {
    "id": “43”,
    “quantity": 1
    }
    ]
    }
    payload: {
    orderId: “42”,
    itemId: “43”,
    quantity: 1
    }

    View Slide

  25. payload: {
    orderId: “42”,
    itemId: “44”,
    quantity: 2
    }
    AGGREGATES
    Example
    25
    {
    "id": “42”,
    "status": "OPEN",
    "items": [
    {
    "id": “43”,
    “quantity": 1
    },
    {
    "id": “44”,
    “quantity": 2
    }
    ]
    }

    View Slide

  26. AGGREGATES
    Example
    26
    {
    "id": “42”,
    "status": "OPEN",
    "items": [
    {
    "id": “44”,
    “quantity": 2
    }
    ]
    }
    payload: {
    orderId: “42”,
    itemId: “43”
    }

    View Slide

  27. AGGREGATES
    Example
    27
    {
    "id": “42”,
    "status": "PLACED",
    "items": [
    {
    "id": “44”,
    “quantity": 2
    }
    ]
    }
    payload: {
    orderId: “42”
    }

    View Slide

  28. AGGREGATES
    Example
    28
    {
    "id": “42”,
    "status": "PLACED",
    "items": [
    {
    "id": “44”,
    “quantity": 2
    }
    ]
    }
    Order Aggregate

    View Slide

  29. COMMANDS
    29
    Add item to order
    {
    "type": “com.restaurant.AddItemToOrderCommand”,
    "payload": {
    "orderId": “be596c8e…”,
    "itemId": “5d09509c…”,
    "quantity": 1
    },
    "timestamp": “2017-03-25 08:48:51 -03:00”
    }

    View Slide

  30. COMMANDS
    30
    (state, command) -> [event]
    Handling a command

    View Slide

  31. COMMANDS
    31
    How do clients send commands?

    I want to add an item
    to my order!
    ?

    View Slide

  32. COMMANDS
    32
    Reviewing REST
    Resource Collection
    host/api/orders

    View Slide

  33. COMMANDS
    33
    Reviewing REST
    Resource
    host/api/orders/8659a0d6

    View Slide

  34. COMMANDS
    34
    Reviewing REST
    Nested Resource
    host/api/orders/8659a0d6/items/5d1a8457

    View Slide

  35. COMMANDS
    35
    Reviewing REST
    HTTP Methods
    GET
    POST
    PUT/PATCH
    DELETE

    View Slide

  36. COMMANDS
    36
    Reviewing REST
    Hypermedia Formats

    View Slide

  37. COMMANDS
    37
    Commands can be resources

    View Slide

  38. COMMANDS
    Option #1
    Generic “Commands” nested-resource
    38
    POST /orders/8659a0d6/commands
    {
    “type": “AddItemToOrderCommand”,
    "menuItem": “/menu/items/8d30d99“,
    “quantity": 2
    }

    View Slide

  39. COMMANDS
    Option #2
    Command URI
    39
    POST /orders/8659a0d6/items/commands/add
    {
    "menuItem": “/menu/items/8d30d99“,
    “quantity": 2
    }

    View Slide

  40. COMMANDS
    Command discoverability
    40

    View Slide

  41. EVENT SOURCING
    41

    View Slide

  42. 42
    Queries?

    View Slide

  43. QUERIES
    Bad news
    The Event Store is not good for queries
    43
    Most applications
    •A few writes
    •A lot of reads

    View Slide

  44. CQRS
    44

    View Slide

  45. CQRS
    Command
    Query
    Responsibility
    Segregation
    45
    Write ✍
    Read

    View Slide

  46. Service
    CQRS
    46

    Command
    Query
    Publish
    Listen

    View Slide

  47. Service A
    CQRS
    47
    Service B

    View Slide

  48. CQRS
    48
    Command model
    •Command definitions
    •Event definitions
    •The aggregate
    •Aggregate repository
    •Write only API
    Query model
    •Event listeners
    •Query entities
    •Repositories
    •Read only API

    View Slide

  49. DEMO
    49

    View Slide

  50. DEMO
    Online Restaurant
    50
    Service

    View Slide

  51. DEMO
    Online Restaurant
    51

    View Slide

  52. EXAMPLE: ONLINE RESTAURANT
    52
    Online Restaurant
    Publishes
    Listen to

    View Slide

  53. EXAMPLE: ONLINE RESTAURANT
    53
    Online Restaurant
    Publishes
    Listen to
    Publishes Listen to

    View Slide

  54. TECHNOLOGIES
    Java
    Spring Boot
    Axon Framework
    Spring Data REST
    RabbitMQ
    54
    https://github.com/vvgomes/event-driven-restaurant

    View Slide

  55. SUMMARY
    55

    View Slide

  56. MICROSERVICES + EVENT SOURCING
    Benefits
    •History based queries
    •Audit log by design
    •Immutability
    •User intent
    •Decoupling
    •Resilience
    56
    Challenges
    •Complexity
    •Snapshots
    •Upcasting
    •Race conditions
    •Event contracts
    •Eventual consistency

    View Slide

  57. WHEN
    MICROSERVICES
    MEET
    EVENT SOURCING
    Vinicius Gomes
    57

    View Slide