Building UIs for Microservices
Ethan Garofolo - wroc_love.rb 2019
Microservices
UIs
Who am I?
This is not an “answers” talk
"The scientist is not a person who gives the right answers, [the scientist] is one who asks the right questions.”
Ceci n’est pas un Claude Lévi-Strauss,
mais je ne suis pas artiste.
What I mean by “microservices”
“Monolith” is not a deployment strategy. It’s a data model.
“Monolith” is a data model
id |
password_hash |
subscribed_to_newsletter |
role |
features_used |
“users”
“Monolith” is a data model
identity
subscription
authorization
analytics
id |
password_hash |
subscribed_to_newsletter |
role |
features_used |
“users”
Not cohesive.
4 different domains.
This. Is. MONOLITH!
“Monolith” is a data model
users
products
What are these lines?
Even if it’s on different servers
users
products
What are these lines now?
Even if it’s on different servers
users
products
Say it with me...
Even if it’s on different servers
users
products
Distributed
Even if it’s on different servers
users
products
Distributed
+
Even if it’s on different servers
users
products
Distributed
+
Monolith
Even if it’s on different servers
users
products
Distributed
+
Monolith
=
Even if it’s on different servers
users
products
Distributed monolith
Services are autonomous
Services are autonomous
Services communicate via asynchronous messages
2 flavors
Events and Commands
Events:
{
‘type’: ‘PEN_DROPPED’,
‘payload’: { ‘some’: ‘such’ }
// ...
}
Events and Commands
Events:
{
‘type’: ‘PEN_DROPPED’,
‘payload’: { ‘some’: ‘such’ }
// ...
}
I am past tense
Events and Commands
Events:
{
‘type’: ‘PEN_DROPPED’,
‘payload’: { ‘some’: ‘such’ }
// ...
}
Events and Commands
Events:
{
‘type’: ‘PEN_DROPPED’,
‘payload’: { ‘some’: ‘such’ }
// ...
}
Commands:
{
‘type’: ‘DROP_PEN’,
‘payload’: { ‘other’: ‘such’ }
// ...
}
Events and Commands
Events:
{
‘type’: ‘PEN_DROPPED’,
‘payload’: { ‘some’: ‘such’ }
// ...
}
Commands:
{
‘type’: ‘DROP_PEN’,
‘payload’: { ‘other’: ‘such’ }
// ...
}
I am imperative
Events and Commands
Events:
{
‘type’: ‘PEN_DROPPED’,
‘payload’: { ‘some’: ‘such’ }
// ...
}
Commands:
{
‘type’: ‘DROP_PEN’,
‘payload’: { ‘other’: ‘such’ }
// ...
}
I am imperative
Invalid
commands
Valid
commands
The events literally are the state of the system
This
Not this
PEN_DROPPED
PEN_PICKED_UP
id | status |
1 | picked up |
Basic shape of a system
The services
[
]
The services
Application
[
]
Message Store
Application
[
]
Read model[s]
The services
Message Store
Application
[
]
Read Model[s]
Aggregators
The Services
Message Store
Application
[
]
Read model[s]
Aggregators
The services
NONE OF THIS IMPLIES IT’S A DISTRIBUTED SYSTEM!
Message stores
Building UIs for this kind of system
Mental models - Kind of like texture maps
Mental models - Kind of like texture maps
Image courtesy: http://animalia-life.club/other/human-face-texture.html
Mental models - Kind of like texture maps
Image courtesy: https://www.researchgate.net/figure/Illustration-of-a-typical-texture-mapping-in-a-triangular-mesh-Vertices-a-b-and-c-are_fig9_232735479
?
Don’t wait until you have HTTP forms on top of database tables to consider the UI/UX of a microservices system.
Figure out the desired experience, then figure out the technology
Sometimes nothing is enough
Ignore the async
Possible situations: analytics, when you hate your users
Video view Analytics
Stalling for time
A light disguise
Possible situations: user registration, e-commerce order, bank transfer
wow.
such grace.
very bird.
Have you ever watched their legs when they swim?
User registration
Submits Registration
Application writes RegisterUser command
“Check your email”
Registration service writes SendEmail command
Email service sends email
Embrace the domain model
Validation is part of the domain model!
Possible situations: Operations that need validation, real-time-ish response
Naming an uploaded video
This is
Mr. Grumpy Pants
CRUDe approach
id | name | etc |
884cd10c-32db-4eca-af3b-9c8217700b2e | Lovely name | --- |
Bad words
CRUDe approach
id | name | etc |
884cd10c-32db-4eca-af3b-9c8217700b2e | Lovely name | --- |
Bad words
STOP
CRUDe approach
id | name | etc |
884cd10c-32db-4eca-af3b-9c8217700b2e | Bad words | --- |
otherwise...
!!1!
*evil laughter*
Better approach
videos-884cd10c-32db-4eca-af3b-9c8217700b2e
VideoUploaded
Bad words
Better approach
videos-884cd10c-32db-4eca-af3b-9c8217700b2e
VideoUploaded
InvalidlyNamed
Different views
Lovely name
VideoUploaded
InvalidlyNamed
Different views
Lovely name
You need to fix that name, bucko.
VideoUploaded
InvalidlyNamed
1. Send name
App
Message store
2. Write command
3. Render response
Publishing service
App
Message store
Publishing service
4. Observe command
Process and validate
5. Write success or failure event
4. Begin polling to see if command processed
Aggregator
6. Observe event and update read model
Naming an uploaded video
Takeaways
More info
Additional resources
People to follow:
Scott Bellware - https://twitter.com/sbellware
Nathan Ladd - https://twitter.com/realntl
Greg Young on event sourcing - https://www.youtube.com/watch?v=JHGkaShoyNs?t=2062
CQRS in Node - https://www.youtube.com/watch?v=4k7bLtqXb8c
Happy Coding!