Chapter 13 of 27 · Part 6: External API and UI

UI patterns: micro frontends and live updates

How to split the user interface along service lines and get fresh data to the browser.

key idea / coordinatorservice / good pathin progress / watch outproblem / failureneutral

Who owns the frontend?

Gateways exist to serve user interfaces, so start with the teams that build them.

Layered teams versus stream-aligned teamsIn a layered organization one new control needs work from three teams. A stream-aligned team owns the whole slice, UI and services together.Layered: hand-offsStream-aligned: whole sliceUI layer teamServices teamData team3 teams,3 hand-offsStockUI +servicesone teamPurchaseUI +servicesone teamProfileUI +servicesone team
Why dedicated frontend teams existTeams cite scarce specialists, consistency and hard-to-split single-page apps. Each has a way out that avoids the hand-offs.Reason givenAnother waySpecialists are scarceEmbed them, or an enabling teamWe want a consistent lookStyle guide, shared componentsSingle-page apps are hard to splitMicro frontendsAmazon trades a consistent UI for team autonomy: the AWS console shows it.
From Building Microservices: a team that owns a slice end to end also stays close to its users. Specialists can be embedded, can split time across teams, or can form an enabling team that helps others become self-sufficient.

Frontend decomposition patterns

Microservices can have micro frontends too. The two usual ways are by page and by widget.

Four ways to build the user interfaceA monolithic frontend is one deployable. Page-based and widget-based decomposition split it up. Both lead to micro frontends.Monolithic frontendAll UI state and behavior in one unit.Fine for one team, drifts to silos.Page-based/albums/ goes to the Albums service.Simple. Default for websites.Widget-basedA container page plus widgets, eachowned by the team behind it.Micro frontendsFrontends deployed independently,by page or by widget.Self-contained systems are a related idea: one team owns each web app, no shared UI.
Widgets talk with eventsIn a widget-based page the chart widget raises a custom browser event. Other widgets subscribe and react, like events between services.Page container: navigation and layoutChart widgetbest sellersAlbumSelectedRecommendationsAlbum detailsWatch page weight: each widget may bring its own copy of a framework.
PatternPick it whenWatch out
Monolithic frontendOne team owns UI and servicesSilos if many teams share it
Page-basedYou are building a websiteCross-cutting features fit badly
Widget-basedA rich SPA with several teamsBundle size, clashing dependencies
API calls onlyA feature does not fit a page or widgetEach client re-implements it
From Building Microservices: page-based splitting needs no clever JavaScript or iFrames: the user follows a link and a new page loads. Newman would choose it by default for a website, and widgets for a rich single-page app.

Decomposing the UI itself

The UI is often the last monolith. If every service team must edit one front-end codebase, autonomy is lost. From Practical Event-Driven Microservices Architecture, ch. 9.

One shell, many owned fragmentsEach team ships its own part of the page. A shell composes them.Page shellOrdersowned byorders teamCatalogowned bycatalog teamProfileowned byprofile teamEach fragment talks to its own service or read model and deploys independently.

Another aspect is the style of interaction. A CRUD screen edits fields and hides the business meaning. A task-based UI exposes what the user wants to do, which maps cleanly to commands and events.

CRUD form versus task-based UITask buttons map to commands, so the event says what happened.CRUD: edit every fieldSave order (all fields)UpdateOrder: what changed?Task-based: act on intentChange addressCancel orderAddressChanged eventTask-based screens produce small, meaningful commands, which fits events and CQRS (lessons 10 and 11).

Getting data to the UI

A screen often needs data from several services. The browser should not know about all of them. From Practical Event-Driven Microservices Architecture, ch. 9.

Three ways to feed a screenCall each service, add an aggregating layer, or read a prepared view.UIone callAggregating layerone entry pointMany servicesorders, catalogUIone callRead modelone prepared viewEventsfrom the servicesTop: the layer calls services at request time. Bottom: events fill a view ahead of time.
OptionGood forWatch out
Aggregating layerOne entry point that hides many services.Can become a central coupling point.
Backend for frontendOne tailored API per client (web, mobile).More code to own and keep in sync.
API compositionJoining a few small responses.Slow and fragile for large joins, filtering or paging.
Catalog read modelSearch, filter and sort over many services.Eventually consistent; lesson 11 shows how.
Why composing in the API stops scalingJoining many service responses on every request costs latency and breaks on one failure.Requestlist ordersCall 3 serviceswait for the slowestOne is downwhole page failsA prepared read model answers from one store and stays up when a source service is down.

Pushing events to the browser

A UI that polls wastes calls and shows stale data. Events can travel on to the browser, but a browser cannot join a Kafka consumer group. From Practical Event-Driven Microservices Architecture, ch. 9.

A client manager between broker and browsersA small service consumes events and pushes them to connected clients.Brokerevent streamClient managerknows who is connectedBrowser ABrowser BThe manager filters events per user, so each browser sees only its own data.
TechniqueHow it worksUse when
WebSocketsTwo-way, long-lived connection.The UI also sends frequent messages.
Server-sent eventsOne-way stream from server to browser over HTTP.The UI only needs updates.
WebHooksThe server calls a URL you register.Notifying another system, not a browser.

Describe the event contracts with AsyncAPI, the event-driven counterpart of OpenAPI. It documents channels and messages so teams can generate docs and code.

Recap

Quick check

Why can a browser not simply consume the Kafka topic?
Show answer

It cannot take part in a consumer group. A client manager consumes the events and pushes them over WebSockets or server-sent events.