WHEN MICROSERVICES MEET EVENT SOURCINGVinicius Gomes
1
VINICIUS GOMES
Software developer at ThoughtWorks
vvgomes.com/blog
twitter.com/vvgomes
2
AGENDA
The Traditional Approach
Introduction to Event Sourcing
CQRS
Demo
Summary
3
THE TRADITIONAL APPROACH
4
EXAMPLE
Online Restaurant
5
ONLINE RESTAURANT
Data Model
6
ONLINE RESTAURANT
Services
7
Restaurant
ONLINE RESTAURANT
8
📱POST
GET
I want to open an order!
200 ✔
Restaurant
ONLINE RESTAURANT
9
📱POST
GET
I want to add an item to
my order!
200 ✔
THE TRADITIONAL APPROACH
• Simple to implement
• Technology agnostic
10
GET POST PUT
DELETE
CHALLENGES
11
CHALLENGES
Coupling
12
CHALLENGES
Coupling
Resilience
13
Restaurant
📱POST
GET
I want to add an item to my order!
503👎
CHALLENGES
Coupling
Resilience
Response time
14
CHALLENGES
Coupling
Resilience
Response time
User intent
15
POST /orders/8659a0d6/items/
Add item to order
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 } ] }
EVENT SOURCING
17
EVENT SOURCING
18
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
EVENT STORE
Append only
Sequential
Long-lived
20
AGGREGATES
21
state = reduce(handle, {}, events)
Reducer function
Reducing events into state
AGGREGATES
Example
22
{ }
AGGREGATES
Example
23
payload: { id: “42” }
{ "id": “42”, "status": "OPEN", "items": [ ] }
AGGREGATES
Example
24
{ "id": “42”, "status": "OPEN", "items": [
{ "id": “43”, “quantity": 1
} ] }
payload: { orderId: “42”, itemId: “43”, quantity: 1 }
payload: { orderId: “42”, itemId: “44”, quantity: 2 }
AGGREGATES
Example
25
{ "id": “42”, "status": "OPEN", "items": [
{ "id": “43”, “quantity": 1
}, { "id": “44”, “quantity": 2
} ] }
AGGREGATES
Example
26
{ "id": “42”, "status": "OPEN", "items": [
{ "id": “44”, “quantity": 2
} ] }
payload: { orderId: “42”, itemId: “43” }
AGGREGATES
Example
27
{ "id": “42”, "status": "PLACED", "items": [
{ "id": “44”, “quantity": 2
} ] }
payload: { orderId: “42” }
AGGREGATES
Example
28
{ "id": “42”, "status": "PLACED", "items": [
{ "id": “44”, “quantity": 2
} ] }
Order Aggregate
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”
}
COMMANDS
30
(state, command) -> [event]
Handling a command
COMMANDS
31
How do clients send commands?
📱
I want to add an item to my order!
?
COMMANDS
32
Reviewing REST
Resource Collection
host/api/orders
COMMANDS
33
Reviewing REST
Resource
host/api/orders/8659a0d6
COMMANDS
34
Reviewing REST
Nested Resource
host/api/orders/8659a0d6/items/5d1a8457
COMMANDS
35
Reviewing REST
HTTP MethodsGET POST PUT/PATCH DELETE
COMMANDS
36
Reviewing REST
Hypermedia Formats
COMMANDS
37
Commands can be resources
COMMANDS
Option #1
Generic “Commands” nested-resource
38
POST /orders/8659a0d6/commands
{ “type": “AddItemToOrderCommand”, "menuItem": “/menu/items/8d30d99“, “quantity": 2 }
COMMANDS
Option #2
Command URI
39
POST /orders/8659a0d6/items/commands/add
{ "menuItem": “/menu/items/8d30d99“, “quantity": 2 }
COMMANDS
Command discoverability
40
EVENT SOURCING
41
42
Queries?
QUERIES
Bad news 😔
The Event Store is not good for queries
43
Most applications
•A few writes
•A lot of reads
CQRS
44
CQRS
Command Query Responsibility Segregation
45
Write ✍
Read 📖
Service
CQRS
46
📱
Command
Query
Publish
Listen
Service A
CQRS
47
Service B
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
DEMO
49
DEMO
Online Restaurant
50
Service
DEMO
Online Restaurant
51
EXAMPLE: ONLINE RESTAURANT
52
Online Restaurant
Publishes Listen to
EXAMPLE: ONLINE RESTAURANT
53
Online Restaurant
Publishes Listen to
Publishes Listen to
TECHNOLOGIES
Java
Spring Boot
Axon Framework
Spring Data REST
RabbitMQ
54
https://github.com/vvgomes/event-driven-restaurant
SUMMARY
55
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
WHEN MICROSERVICES MEET EVENT SOURCINGVinicius Gomes
57