The context
The ecosystem already had several business applications built separately, sharing users and needing data to flow between them. The U-App platform aimed to unify that foundation: one entry point for client applications, one source of identity, and autonomous business domains behind it.
The split into services was not driven by load, but by organisation: letting parallel development streams progress without blocking each other at release time.
What I built
API gateway
a single entry point routing to internal services, with centralised authentication and health monitoring.
Back-office service
commercial management: leads, contracts, teams, telesales activity tracking.
Loyalty currency
accounts, transactions, conversions and partner redemptions.
Gamified quiz engine
levels, condition-based quests, questionnaires and answer tracking.
Content service
targeted news, FAQ, privacy policies, translations and reference data.
Identity directory
a centralised user repository.
Realtime server
event broadcasting to client applications.
Architecture & technical decisions
The gateway insulates client applications from the internal topology: they query one address, without knowing the service split or its evolution. It also carries authentication, avoiding a reimplementation in every service.
Services communicate over an event bus rather than direct calls. That choice structures everything else: each service publishes what it does and consumes what interests it, without knowing who is listening. An unavailable service does not block the others — it catches up when it restarts.
Identity is centralised in a directory, a classic choice in multi-application environments: one user, one repository, and an access revocation that applies everywhere instantly.
Realtime runs through a dedicated service with application-key authentication rather than being embedded in each service — one persistent client connection, whatever the number of domains involved.
Technical challenges
The real cost of microservices. This architecture moves complexity rather than removing it: what was a function call becomes a fallible network call, to be traced and retried.
Eventual consistency. Without a global transaction, you must accept that services are temporarily out of sync and design the interface accordingly.
Observability. Following a user action across four services requires correlated logging, without which any diagnosis becomes an investigation.
Message versioning. Changing the shape of a published event affects every consumer: changes must stay backward-compatible.
The development environment. Running nine services plus their dependencies on one machine demands careful orchestration to stay usable day to day.