GET /presentation HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"what": "Evolving Compositional User Interfaces",
"where": "NDC Oslo 2019",
"when": "2019-06-21T10:20+02:00"
}
Asbjørn Ulsberg
Developer Experience Janitor
Thomas Presthus
Consultant and architect
– @presthus
– thomas@erus.no
– bit.ly/ddd-cqrs
@asbjornu –
asbjorn.ulsberg@payex.com –
slack.httpapis.com –
<problems>
APIs are great
UI
Application services
Domain model
Data access
UI
Service
Domain
DAL
UI
Service
Domain
DAL
UI
Service
Domain
DAL
Remember how easy these were..?
service service service service service
service service service service
Where’s my
frontend?
We need this new feature. I
don’t know what you mean
by “cross-cutting” – you just
spent a year tearing our
system into “microsofts” or
something, we need to
deliver value now!
- John P. Roduct
Considerations to make
Organization
● How many developers?
● How many teams?
● One system, or many systems?
● One application or many?
Needs, requirements and expectations
● Uniform look and feel
● Internal application or public product
● Who are your users?
● Pace and speed
○ Delivery
○ Time to market
Skills and existing architecture
● Do you need training?
● Architectural alignment
● Technology stack(s)
● Operational perspective
What do we want?
Scale
development
Maintain distribution
& cohesion
Provide
composition of
user interfaces
Compositional
user interfaces
Technical patterns
Diving towards
deeper understanding with
models
Where to start?
Consensus seems to be
that composition is
good 👍
Here be dragons.
service service service service service
service service service service
Where’s my
frontend?
The monolithic
frontend
Monolithic frontend
● Composition takes place in separate frontend application
● Versioned independently
● Usually data based composition:
○ Application invokes (REST-ful) APIs of the services it depends on
○ Application has intimate knowledge of inner workings of its dependent services
○ Application has sole responsibility for look-and-feel, placement and layout
● Requires extra effort to handle failures, down-time of dependencies
● Easy to work with UX
Frontend
service service service service service
One, big team for the
whole solution
Backend, frontend and
database
The monolith
UX/UI team
Frontend
Frontend monolith
Backend
team
1
Backend
team
2
Backend
team
3
DEMO
Monolithic frontend
Monolithic
Frontend
Pros
• Quick and easy to get up and running
• Can be implemented both server- and client
side
Cons
• Frontend becomes bottleneck
• Lock-step deployments
• Loses autonomy - tightly coupled
• All the pain from monolithic architecture
“the mixture of things or people that are
combined to form something […]”
Cambridge Academic Content Dictionary
Composition (noun)
service service service service service
service service service service
U
I
U
I
U
I
U
I
U
I
U
I U
I
U
I U
I
ESI / SSI
Living life on the edge
Edge-Side / Server-Side Includes
● Establishes a middleware component for merging content
○ Can be part of the application (SSI) or an independent component (ESI)
● Request is routed to primary service responsible for handling it
● The primary service prepares a response with inclusion parts
● The middleware fetches resources for the inclusion parts and embeds
them into the body before returning the response to the requesting
client
Edge-Side Includes
● Composition happens on the edge
○ ie. out-of-bound of application
● Commonly achieved with caches, reverse proxies
and/or load balancers:
○ Varnish
○ Nginx
● Mostly used for static content
● Dynamic/personal content: Use with care!
Server-Side Includes
● Composition typically takes place at application
level or in the web server
● Most often achieved in the web server:
○ Apache2 support
○ IIS support
● Can easily be achieved directly in your
application by implementing a middleware
pipeline
● Take same precautions as ESI
ESI example
<html>
<body>
<nav>
<esi:include src="http://navigation-service/nav" />
</nav>
<div>
<h1>Hello, world!</h1>
</div>
<div>
<esi:include src="/related" />
</div>
</body>
</html>
GET /frontpage
Varnish / ESI middleware
Handle primary
request
Fetch navigation
resource
Fetch related
resource
Response ready
Embed resources
GET /nav
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home</a>
</li>
</ul>
GET /related
<div class="card">
<img src="..." class="card-img-top">
<div class="card-body">
<h5 class="card-title">See also</h5>
<p class="card-text">...</p>
<a class="btn btn-primary">Go somewhere</a>
</div>
</div>
<html>
<body>
<nav>
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home</a>
</li>
</ul>
</nav>
<div>
<h1>Hello, world!</h1>
</div>
<div>
<div class="card">
<img src="..." class="card-img-top">
<div class="card-body">
<h5 class="card-title">See also</h5>
<p class="card-text">...</p>
<a class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
</body>
</html>
Edge- and
Server-side
Includes
Pros
• Scales well with static resources
• Open source components readily available
• W3C standard language specification
Cons
• Primary handler must know about resources to include
• Mostly suited to embedded static bits
Server-side composition
Server-side composition
● Building applications that compose and render pages on the server
○ Full pages with layout or partials
● Several applications can be linked together
○ Chain of Responsibility
○ Layers of composition
● Similar to BFF, but without the B
● Technology agnostic
Server-side composition
● Also used for isomorphic applications
● Preparing layout and immediate page compositions
○ Load time / caching
○ Responsiveness
○ SEO
● Same code on server- and client side
Client-side composition
Client-side composition
● Usually accomplished with a Single Page Application (SPA)
○ JavaScript (et al) allows us to piece together blocks in real-time
● In order to avoid a monolithic SPA, we need to rethink how SPAs are
architected:
○ Communicating through the DOM with events
○ iFrames and post-messages
○ Shell application dictates layout + look-and-feel
Client-side composition
Do not create another monolith!
We are used to developing SPAs in a fashion that leans towards monolithic
tendencies.
Resist the urge. Try instead breaking established patterns and push for
change.
Client-side composition
Further use of Web Components.
Every service / team builds their own components in their technology stack,
wrapping it in custom elements:
<catalog-related></catalog-related>
Treat component as Open-Host service with published API.
DEMO
Client-side composition with web components
Client-side
composition
Pros
• Web Components specification
• Technology agnostic
• Clean interfaces with published contract
between services
Cons
• Browser support
• Requires rethinking of client-side architecture - can
be hard in existing teams
Hybrid compositional
solutions
Classifying your needs
Documents-to-Applications Continuum (Aral Balkan)
static documents,
connected via links
pure behaviour driven,
contentless application
Read more at micro-frontends.org
Server-side
composition and
integration
Application lives
almost entirely in the
browser
Hybrid approach
Instant feedback,
progressive
Modelling composition
Image service
Cart service
Cart service
Pricing service
Frontend
service service service service service
Dependency Inversion
Frontend
service service service service service
Frontend
service service service service service
Compositional model Compositional model
Modelling composition
● Layout
● Content
● Relation
● Navigation
● Templating
● Look and feel
● Forms
● Data capture
● Behavior and intent
Case: Search and filter
Brief
As a Payment Solution Provider, we help
merchants receive payments from their
customers.
To ensure high conversion rates, we
provide several different payment
instruments, or payment methods: Credit
card, Invoice and MobilePay.
Sometimes, merchants receive support
calls from their customers, and needs to
find specific payments in our
administration portal. This requires a
user-friendly search-and-filter interface.
Credit Card
Invoice
Mobile Pay
Payment
Search
Service
Payment Search Frontend
Payment Search
Transaction number Date Amount Search
We need filters
on payment
method specific
criteria!
Payment Search
Transaction number Date Amount Search
Payment method
Credit Card Primary account no Expiration date Cardholder name
Invoice Invoice number Due date Social security no
Mobile Pay Phone number
Credit Card
Invoice
Mobile Pay
Payment
Search Service
Payment Search Frontend
● Primary Account Number
● Expiration Date
● Cardholder Name
● Invoice Number
● Due Date
● Social Security Number
● Phone Number
This is fine
“We’re going to implement 4 new payment
methods every year”
Credit Card
Invoice
Mobile Pay
Payment
Search Service
Payment Search Frontend
X
Y
Payment Search Frontend
Autonomy is gone
We now have a distributed
monolith
We need to invert the
dependency graph
Let's try some modelling!
Payment
method
Payment
Search Service
Payment Search Frontend
Payment Filter
Criteria
Type Widget
Method
Registers its filters with...
Fetches
available
filters
from...
Cache
{
"paymentMethod": "CreditCard",
"filters": [
{
"key": "panumber",
"name": "Primary Account",
"input": {
"widget": "text-box"
}
},
{
"key": "expiration",
"name": "Expiry Date",
"input": {
"widget": "month-year",
"requirements": [
{
"criteria": "date",
"rule": "future"
}
]
}
}
]
}
Making a
protocol of the
model
Data-based composition
This is essentially data-based composition.
Our independent payment method services all conform to a model with a
published language protocol. This model represents interactions in the
context of search and filter.
The frontend is independent from and not aware of the underlying services.
It only knows the model, and is driven by the defined protocol.
Hypermedia
Hypermedia based composition
● Employ web semantics to drive composition
● Composition mechanism is shifted from the underlying services
● Model interactions as relations
○ Provides context
○ Provides navigation handles
○ Model serves as protocol
● Composition can take place both server- and client side
Hypermedia based composition
"operations": [
{
"method": "PATCH",
"rel": "choose-account-credentials next",
"href": "https://host/795a1a05/852a",
"contentType": "application/json",
"expects": {
"fields": ["email", "msisdn"],
"options": {
"email": ["thomas@mucon.com", "thomas@gmail.com"],
"msisdn": ["+4745123456", "+4659123465"]
},
"contentType": "application/json"
}
},
{
"method": "GET",
"rel": "view-shipping-details",
"href": "https://host/1352ba4/shipping-details",
"contentType": "application/json"
}
]
{
"input": {
"email": "thomas@mucon.com",
"msisdn": "+4745123456",
"nationalIdentifier": {
"socialSecurityNumber": "12048512345",
"countryCode": "NO"
}
},
"operations": [..]
}
Hypermedia based composition
You can also build upon existing standards:
● HAL
● Collection+JSON
● Siren
● JSON-LD
Or at least draw inspiration from them!
Protocol is key.
Hypermedia
based
composition
Pros
● Web semantics
● Existing standards
● Caches well
● Easy to argue for
Cons
● Not a “full solution”
● Relations takes effort to model
Message based composition
Asynchronous, decoupled rendering of partial layouts
Message based composition
● Services provide partials based on events
○ As soon as a request is made, its intent is published to a message stream and
delivered to other services.
○ These services provide partial HTML that is of interest to the request.
○ Partials contains metadata for placement into layout.
● A composer subscribes to partials that are made available, and embeds
them into the finished layout.
● Request and partials, together with immediate messages, are correlated
with an ID.
● Upon completed composition, the composer returns the HTML to the
client making the request.
Route
r
Composer
GET /books/DDD/1fa5cd
Category marketing
Book inventory
Purchase behavior
Book requested
ID: 1fa5cd
Category: DDD
Partial available
Section: cross-sell
Content: HTML
Other books in
same category
Partial available
Section: cross-sell
Content: HTML
Often bought
together with
Pricing
Partial available
Section: shop
Content: HTML
Price - buy
it now
Page layout initiated
Content: HTML
Descript
ion of book
$$$
Message based
composition
Pros
● Fully asynchronous
● Can be made quite
autonomous
● Event driven
● Scales well
Cons
● Many moving wheels
● Message broker single point of
failure
● Hard to know when page is
ready
Hybrid message-based composition
Request is routed to primary source
Composer builds up preliminary layout
● Waits for determined
amount of time, e.g.
250ms
Preliminary layout is rendered in browser
Page is now usable
Message sink is setup in browser
Additional partials are pumped to browser
Client-side composer finishes the page
gradually
● Websocket, long-polling,
etc
Combining it all
● Complex systems require simple solutions
● Strive to choose the best fit for the job
● There is no one pattern to rule them all
○ Feel free to combine different compositional patterns
○ Be sure to have a strategy and alignment across teams
● Challenge existing paradigms and don’t be afraid to model
● Technical patterns are only half the solution
Some final considerations..
● Authentication and authorization
○ OAuth2 and OpenId connect
○ Embrace delegation
● Appearance
○ Styling and CSS, imagery
○ Develop a design guide
● Navigation
○ Depends on use case
○ Try to use HTTP for what it’s good for
1941
The Garden of Forking Paths
Jorge Luis Borges
“Hypertext”
“Hypermedia”
1963
1968
“The Mother Of All Demos”
oN-Line System
1987
1989
“WorldWideWeb”
2000
Architectural Styles and the Design of
Network-based Software Architectures
By
“Representational State Transfer”
“REST”
Roy Thomas Fielding
Hypermedia
Hypermedia: Affordances
Hypermedia: Affordances
Do people know what to do based on
what they see?
Hypermedia: Affordances
Do machines know what to do based on
what they see?
Hypermedia
<a href="/toaster">Toaster</a>
<img src="toaster.jpeg" alt="Toaster">
<video src="toaster.mp4">Toaster</video>
<form action="/toaster" method="post" rel="on">
<button type="submit"
name="state"
value="on">Turn on</button>
</form>
Composition
noun
• The act of combining parts or elements to form a whole
B
A
B
postMessage()
A
B
postMessage()
A
Thank You!
Asbjørn Ulsberg
Developer Experience Janitor
Thomas Presthus
Consultant and architect
– @presthus
– thomas@erus.no
– bit.ly/ddd-cqrs
@asbjornu –
asbjorn.ulsberg@payex.com –
slack.httpapis.com –