Ecommet
Topic 61 of 75

Design and Implementation Patterns

Patterns for structuring services and their edges: strangler fig, sidecar, ambassador, anti-corruption layer, backends for frontends, gateway routing, offloading and aggregation, external configuration, compute resource consolidation and leader election.

Intermediate 5 min read 3 quiz questions

Jump to the quiz

In a nutshell

  • Strangler fig replaces a legacy system piece by piece behind a routing layer.
  • Sidecar and ambassador move cross-cutting concerns (proxies, TLS, retries, logging) into a helper process next to the app.
  • Anti-corruption layer translates between your model and a legacy or third-party one, so their quirks do not leak in.
  • Gateway patterns (routing, offloading, aggregation) and backends for frontends shape what clients see.

Strangler fig

Rewriting a large legacy system in one go is risky. Instead, put a routing layer in front, build one feature at a time in the new system, and route that feature's traffic to it. The legacy system shrinks until it can be switched off, like the strangler fig vine that slowly replaces its host tree (Martin Fowler named the pattern after it).

Strangler fig migration

Strangler fig migration Users → Router / proxy Router / proxy → New service: migrated Router / proxy → Legacy app: not yet UsersRouter / proxyNew service/checkout, /searchLegacy appeverything elsemigratednot yet
The router sends migrated paths to the new service and everything else to the legacy app, one feature at a time.
Diagram as text
  • Users → Router / proxy
  • Router / proxy → New service: migrated
  • Router / proxy → Legacy app: not yet

Sidecar and ambassador

A sidecar is a helper process deployed next to each service instance (in the same pod or host), handling shared concerns: log shipping, metrics, TLS, configuration reloads. The app stays focused on business logic, in any language. An ambassador is a sidecar specialised for outgoing calls: retries, timeouts, circuit breaking, routing. Service meshes (Istio, Linkerd) run a proxy sidecar beside every service to provide these features everywhere.

App with sidecar proxies

App with sidecar proxies Orders app → Sidecar proxy: localhost Sidecar proxy → Sidecar proxy: mTLS, retries Sidecar proxy → Payments app: localhost Orders appSidecar proxySidecar proxyPayments applocalhostmTLS, retrieslocalhost
Each app talks only to its local proxy. The proxies handle mutual TLS, retries and metrics between services.
Diagram as text
  • Orders app → Sidecar proxy: localhost
  • Sidecar proxy → Sidecar proxy: mTLS, retries
  • Sidecar proxy → Payments app: localhost

Anti-corruption layer

When your clean new service must talk to a legacy system or an awkward third-party API, put a translation layer between them. It converts their data model, naming and error conventions into yours, so the rest of your code never depends on theirs, and replacing them later touches one place.

Backends for frontends

A mobile app, a web app and partner integrations need different data shapes and amounts. Instead of one general API that fits none of them well, give each client type its own thin backend (a BFF), owned by the team building that client, which calls the underlying services and returns exactly what its screens need.

Gateway routing, offloading and aggregation

  • Gateway routing: one public entry point routes requests to the right backend by path or host, so clients do not know the internal layout.
  • Gateway offloading: move shared work into the gateway: TLS termination, authentication, rate limiting, compression.
  • Gateway aggregation: one client request fans out to several services and the gateway combines the answers, saving the client many round trips (especially on mobile networks).

These are the jobs of an API gateway; see the API gateway topic.

External configuration, consolidation, leader election

  • External configuration store: keep settings and feature flags in a central service (with versioning and access control) instead of inside each deployment, so they can change without redeploying.
  • Compute resource consolidation: run several small, low-load components together on shared compute to cut cost and overhead, while keeping heavy or critical ones isolated.
  • Leader election: when exactly one instance must coordinate (run the scheduler, own a partition), elect it through a consensus-backed lease; see the Leader election and consensus topic.
PatternUse when
Strangler figReplacing a legacy system without a big-bang rewrite
SidecarMany services need the same helper, in any language
AmbassadorOutgoing calls need retries, timeouts, routing
Anti-corruption layerIntegrating with a legacy or messy external model
Backends for frontendsDifferent clients need very different APIs
Gateway routing / offloading / aggregationOne entry point, shared edge work, fewer client calls
External configuration storeConfig must change without redeploys
Compute resource consolidationMany tiny workloads wasting resources
Leader electionExactly one instance must coordinate

Common mistakes

  • Big-bang rewrites instead of incremental strangling.
  • A BFF that grows business logic and becomes another monolith.
  • Letting a third-party API's model spread through your codebase.
  • Adding a service mesh before having enough services to justify it.

Interview questions

Try answering out loud before you open each one.

How would you migrate a monolith to services safely?

Use the strangler fig pattern: put a proxy or gateway in front, extract one capability at a time behind a clear interface (with an anti-corruption layer where the old model is messy), route its traffic to the new service, compare results, then delete the old code. Start with a low-risk, well-bounded capability.

Check yourself

1. Which pattern replaces a legacy system gradually behind a router?
Show the answer

Answer: Strangler fig. Feature by feature, traffic moves to the new system.

2. A helper process next to each app handles TLS and log shipping. This is a…
Show the answer

Answer: Sidecar. It is deployed alongside the app instance.

3. The mobile app needs a compact API different from the web's. Which pattern?
Show the answer

Answer: Backends for frontends. Each client type gets its own thin backend.

Further reading

Your notes

Saved in this browser as you type.

Finished this topic?

Mark it read to track your progress, then carry on with the next one.

Next topic