Case study: Distributed control plane
This case study shows Mateu used across multiple microservices, each owning its own UI, with a shell that federates them into a single backoffice. It illustrates the most common real-world patterns together.
Architecture
Section titled “Architecture”flowchart TD Browser --> Renderer["Mateu Renderer"] Renderer --> API["Mateu API / Shell"] API --> CS["Content Service\n(owns UI + domain)"] API --> CP["Control Plane\n(owns UI + domain)"] API --> SS["Static Server\n(owns UI + domain)"] API --> EC["EventConductor\n(owns UI + domain)"]Each service owns its domain and its UI. The shell owns nothing except the composition.
Service-owned UI
Section titled “Service-owned UI”Each service exposes its own @UI:
@UI("/_content-service")public class ContentServiceHome {}Each module defines its own menu, routes, and orchestrators. No shared frontend repository is needed.
The shell aggregates them using RemoteMenu:
Shell ├── Content Service UI ├── Control Plane UI └── Other modulesSee Service-owned UI modules for the full pattern.
DTO to row to UI
Section titled “DTO to row to UI”Query results flow through a mapping step before reaching the grid:
new ChangeRow( dto.pageId(), dto.page(), dto.country(), dto.language(), new Status(...), new ColumnAction("compare", "Compare"))DTO → Row → Component → UIThe row is a UI read model — a record designed for display, not for the domain. See Query services and UI rows.
Actions as contracts
Section titled “Actions as contracts”The action id is the only contract between the UI and the backend:
new ColumnAction("compare", "Compare")User click → actionId → backend → use caseNo logic lives in the frontend. The backend decides what “compare” means.
Lookups across services
Section titled “Lookups across services”Lookup fields can call query services from other services:
@Lookup(search = LabelOptionsSupplier.class, label = LabelLabelSupplier.class)String labelId;UI → Supplier → Query Service → ResultsThe supplier is a Spring bean. It can call any data source — local or remote. See Lookups backed by query services.
Workflows and forms
Section titled “Workflows and forms”Mateu triggers workflow steps, renders the required form, and handles the result:
UI → Workflow Engine → Form → User Input → ExecutionSee Workflow and forms integration.
Stateless backend
Section titled “Stateless backend”Each Mateu page class is stateless. No mutable fields survive between requests. State lives in:
- The JWT (user identity, permissions)
- The database (content, job status)
- The browser (form state, via
stateanddatacontexts)
This enables horizontal scaling with no sticky sessions.
Key patterns
Section titled “Key patterns”| Pattern | Where documented |
|---|---|
| Service-owned UI modules | Service-owned UI modules |
| Query services and UI rows | Query services and UI rows |
RemoteMenu aggregation | Navigation and menus |
| SSE for long operations | Actions: SSE |
| JWT-based authorization | Security |
@EyesOnly per role | Security |
Summary
Section titled “Summary”Mateu is a UI orchestration layer for distributed systems. Backend teams can build complete, federated backoffices without owning a frontend stack or building a separate API layer for the UI.
- Service-owned UI modules — how each service exposes and composes its UI
- SSR to SSG case study — another detailed example with SSE and per-row dynamic actions
- Mateu in hexagonal architecture — the architectural foundation for this pattern