Design Patterns for Microservice Architecture
This article explains key microservice design patterns—including Database per Service, Event Sourcing, CQRS, BFF, API Gateway, Strangler, Circuit Breaker, Externalized Configuration, and Consumer‑Driven Contract Testing—detailing their advantages, disadvantages, suitable scenarios, and example technologies for building scalable, resilient backend systems.
Microservice Architecture Design Patterns
Software design patterns provide reusable solutions to common problems. In the context of microservices, a series of patterns help achieve best‑practice architectures.
Database per Microservice
Instead of sharing a single central database, each microservice should own its own logical data store, which may be physically isolated or use separate schemas/tables. This reduces coupling and aligns with domain‑driven design.
Advantages
Data is fully owned by the service.
Coupling between development teams is reduced.
Disadvantages
Data sharing between services becomes more challenging.
Maintaining ACID transactions across services is difficult.
Designing how to split a monolithic database is complex.
When to use
Large enterprise applications.
When teams need full control to scale development speed.
When not to use
Small‑scale applications.
Single‑team ownership of all services.
Technology examples : Any SQL or NoSQL database that supports logical isolation (separate tables, collections, schemas, or databases).
Event Sourcing
Instead of persisting only the current state, every state‑changing event is stored immutably. Services can reconstruct state by replaying events, enabling atomic operations and a complete audit trail.
Advantages
Provides atomic operations for highly scalable systems.
Automatically records entity change history.
Supports loosely coupled, event‑driven microservices.
Disadvantages
Reading entities requires additional storage (CQRS).
Increases overall system complexity; often needs domain‑driven design.
Must handle idempotency and possible event loss.
Changing event schemas is challenging.
When to use
High‑scalability transactional systems using relational or NoSQL databases.
Elastic, fault‑tolerant microservice architectures.
Message‑driven or event‑driven applications (e‑commerce, booking).
When not to use
Low‑scalability transactional systems on SQL databases.
Simpler microservices that can synchronously exchange data via APIs.
Technology examples : EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, DynamoDB; frameworks such as Lagom, Akka, Spring, akkatecture, Axon, Eventuate.
CQRS (Command Query Responsibility Segregation)
When using Event Sourcing, reading data becomes complex. CQRS separates write (command) and read (query) models, allowing independent scaling and optimization.
Advantages
Faster reads in event‑driven microservices.
Higher data availability.
Independent scaling of read and write stores.
Disadvantages
Read store is eventually consistent.
Overall system complexity increases; misuse can jeopardize projects.
When to use
High‑scalability microservices employing Event Sourcing.
Complex domain models requiring different read/write performance.
Systems where read/write load differs significantly.
When not to use
When a simple snapshot approach suffices.
When read and write loads are similar.
Technology examples
Write stores: EventStoreDB, Kafka, Kinesis, Azure Event Hub, etc.
Read stores: Elasticsearch, Solr, Cloud Spanner, Amazon Aurora, Neo4j.
Frameworks: Lagom, Akka, Spring, akkatecture, Axon, Eventuate.
Backend for Frontend (BFF)
When multiple UI clients (web, mobile, TV, etc.) have different API needs, a dedicated backend per UI can tailor responses, improve security, and reduce chatter with downstream services.
Advantages
Separates concerns, allowing UI‑specific optimization.
Provides higher security.
Reduces frequent communication between UI and downstream services.
Disadvantages
Potential code duplication across BFFs.
Management overhead for many BFFs.
Requires careful design to keep business logic out of BFF.
When to use
Multiple UIs with distinct API requirements.
Security‑driven need for an extra layer.
Micro‑frontend architectures.
When not to use
Multiple UIs that share the same API.
Core microservices not deployed in a DMZ.
Technology examples : Any backend framework (Node.js, Spring, Django, Laravel, Flask, Play, …).
API Gateway
An API gateway sits between clients and microservices, acting as a façade, routing requests, aggregating responses, and handling cross‑cutting concerns such as SSL termination, authentication, rate limiting, and logging.
Advantages
Provides loose coupling between front‑end and back‑end services.
Reduces number of client‑to‑service calls.
Enables centralized security and cross‑cutting concerns.
Centralized management of logging, monitoring, throttling, load balancing.
Disadvantages
Potential single point of failure.
Additional network latency.
Can become a bottleneck if not scaled.
Extra maintenance and development cost.
When to use
Complex microservice architectures where it is almost mandatory.
Large enterprises needing centralized security and cross‑cutting concerns.
When not to use
Small projects or startups where security/central management is not a priority.
Very few microservices.
Technology examples : Amazon API Gateway, Azure API Management, Apigee, Kong, WSO2 API Manager.
Strangler
The Strangler pattern enables incremental migration from a monolith to microservices by routing requests for replaced functionality to new services while keeping the legacy system alive until fully retired.
Advantages
Safe migration of monolith to microservices.
Parallel development of new and existing features.
Controlled migration pace.
Disadvantages
Sharing data stores between legacy and new services is challenging.
Facade (API gateway) adds latency.
End‑to‑end testing becomes harder.
When to use
Incrementally migrate large backend monoliths to microservices.
When not to use
Small monoliths where full replacement is simpler.
Inability to intercept client requests to the legacy system.
Technology examples : API gateway frameworks.
Circuit Breaker
In synchronous microservice calls, failures can cascade. A circuit breaker monitors failure rates and short‑circuits calls when a threshold is exceeded, preventing resource exhaustion.
Advantages
Improves fault tolerance and resilience.
Prevents cascading failures.
Disadvantages
Requires complex exception handling and monitoring.
Needs manual reset mechanisms.
When to use
Synchronous, tightly‑coupled microservice architectures.
Services that depend on multiple downstream services.
When not to use
Loose‑coupled, event‑driven architectures.
Services without downstream dependencies.
Technology examples : Hystrix, Resilience4j, Polly, service mesh implementations.
Externalized Configuration
Storing configuration outside the codebase (environment variables, external files, configuration servers) separates build from runtime, reduces security risk, and allows changes without rebuilding.
Advantages
Production credentials are not in source code, minimizing security leaks.
Configuration changes do not require rebuilding.
Disadvantages
Requires a framework that supports externalized configuration.
When to use
Any important production application.
When not to use
Proof‑of‑concept or throw‑away prototypes.
Technology examples : Most modern enterprise frameworks (Spring Cloud Config, .NET Core options, etc.).
Consumer‑Driven Contract Testing
Teams write contract tests from the consumer’s perspective, specifying expected requests and responses. Providers run these contracts as part of their CI pipeline, ensuring API compatibility.
Advantages
Detects unintended API changes quickly.
Reduces surprises and increases robustness in large enterprises.
Improves team autonomy.
Disadvantages
Additional effort to develop and integrate contracts.
If contracts diverge from reality, production failures may occur.
When to use
Large enterprise applications with many independently developed services.
When not to use
Small applications owned by a single team.
Stable services that rarely change.
Technology examples : Pact, Postman, Spring Cloud Contract.
Conclusion
Microservice architecture brings scalability and long‑term benefits, but it is not a universal silver bullet. Teams should follow best practices and adopt proven design patterns such as Database per Service, Event Sourcing, CQRS, Saga, BFF, API Gateway, Circuit Breaker, Strangler, Externalized Configuration, and Consumer‑Driven Contract Testing to build robust, maintainable systems.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.