MicroservicePatterns.com

Suggestions

  • PagePattern catalogAll patterns by category.
  • LabCircuit Breaker and Retries labCrash a dependency and tune the breaker.
  • LabSaga labFail a step and watch the compensations run.
  • PagePractice questionsScenario questions with explanations.
  • PageDesign reviewCheck your own architecture for anti-patterns.
Architecture

Layers and cross-cutting concerns

A microservice system has technical layers, from the screens people use down to the data. Who owns them is a separate question. Product teams own a business capability through every layer, and platform teams own the foundations each layer is built on. Concerns that every layer shares are solved once, with the right mechanism. For how to organise the teams themselves, see teams and ownership.

The layers

From the screen to the database

  1. Web and mobile clients

    The screens people use: web apps in the browser, and iOS and Android apps that stay installed for months.

    Owned by: Product teams build the features. Web and mobile platform teams own the shell, design system and release process.

  2. Edge

    The single way into the system: CDN, API gateway, rate limits, routing and authentication of incoming requests.

    Owned by: The infrastructure platform team.

  3. Backends for frontends

    A small backend per client experience that fetches, combines and reshapes data for its screens.

    Owned by: The team that owns the client, often in the client's language so it can realistically own both.

  4. Domain services

    Services split by business capability, each with its own business rules and its own data.

    Owned by: Product teams, one per business capability, who build and run their services.

  5. Data and messaging

    Each service's private database, and the broker that carries events between services.

    Owned by: Each service owns its data. The platform runs databases and the broker as self-service products.

  6. Runtime and delivery

    Where everything runs and how it gets there: clusters, the mesh, configuration, pipelines and templates.

    Owned by: The infrastructure platform team, offered to every other team as a paved road.

Cross-cutting concerns

Solve each concern with the right mechanism

Not every shared concern belongs in the same place. Sorting them by how they are solved tells you where each one lives and who owns it.

The hardest ones

Concerns that cross every layer

These have to behave the same way from the user's screen to the database. Separate solutions per layer do not join up, so the platform defines the contract once and provides an implementation for each stack.

Identity and security

A user signs in once, and that identity has to travel from the app through the gateway and BFF to every service, without each layer inventing its own scheme.

The contract: One token format, issuer and set of scopes, verified the same way in every layer.

Clients
The app shell signs the user in and attaches the token to every call.
Edge
The gateway validates the token and relays it.
BFF
Swaps a browser session for an access token and passes it on.
Services
The chassis verifies the signature, and each endpoint checks the scopes it needs.
Between services
Mutual TLS from the mesh proves which service is calling.

Observability

When a tap or a click is slow, you need one trace from the user's device to the database call, and logs you can join on the same ID.

The contract: Standard trace context headers, such as W3C Trace Context with OpenTelemetry, one log format and agreed metric names.

Clients
The shell starts a trace at the user's action and sends its context with each request.
Edge and BFF
Pass the trace context on to every downstream call.
Services
The chassis propagates the context and writes the trace ID into every log line.
Messaging
Events carry the trace context, so asynchronous steps join the same trace.

Errors and resilience

A failure deep in the backend has to turn into a sensible message on the user's screen, not a blank page or a raw stack trace.

The contract: One error model with stable codes, such as RFC 9457 problem details, and agreed timeout budgets per call chain.

Services
Return errors in the agreed model, and fail fast with timeouts and circuit breakers.
BFF
Applies fallbacks for optional data and maps errors to what the client can act on.
Clients
Map error codes to messages, and offer a retry where it is safe.

Versioning

Web clients update on the next page load, but mobile apps stay installed for months, so every layer must keep working with older callers.

The contract: Add-only API changes, a deprecation policy, a minimum supported app version and contract checks in every pipeline.

Clients
Read responses tolerantly and send their app version with each request.
BFF
Translates for old app versions, so domain services can evolve.
Services
Make additive changes and verify consumer contracts before deploying.
Events
Evolve schemas compatibly, so old consumers keep reading new events.