Designing Clear Microservice Layers: Facade, Application, Domain, Infrastructure

This article explains a layered microservice architecture, detailing the responsibilities of Facade, Application, Domain, and Infrastructure services, the interaction patterns within and between services, strict versus loose layering, and the roles of various data objects such as PO, DO, DTO, and VO.

Thoughts on Knowledge and Action
Thoughts on Knowledge and Action
Thoughts on Knowledge and Action
Designing Clear Microservice Layers: Facade, Application, Domain, Infrastructure

Service Layer Model

A typical microservice is organized into five logical layers, each with a well‑defined responsibility:

Facade Service (User‑Interface layer) : Exposes REST/JSF endpoints, parses configuration files, and forwards requests to the Application layer. After processing, it assembles Domain Objects (DO) into Data Transfer Objects (DTO) or View Objects (VO) for the front‑end.

Application Service (Application layer) : Represents user actions, composes and orchestrates lower‑level services, determines the execution order of business use cases, and provides coarse‑grained APIs to callers (e.g., API gateway or other microservices).

Domain Service (Domain layer) : Encapsulates core business logic that spans multiple entities. It receives DOs, performs domain‑level calculations, and returns DOs to the Application layer.

Infrastructure Service (Infrastructure layer) : Supplies technical resources such as databases, caches, and message queues. It implements repository interfaces (via Dependency Inversion) that hide persistence details from upper layers.

RPC Service : Implements an anti‑corruption layer for third‑party system interfaces. It is kept separate from the Infrastructure layer to avoid leaking external contracts into the core domain.

Service Invocation Scenarios

Intra‑service calls: Facade → Application → Domain → Infrastructure (repository) within the same microservice.

Inter‑service calls: External clients invoke Facade through an API gateway; the Facade forwards to the Application service, which may call other microservices directly or via the gateway.

Event‑driven communication: Domain events are published to an internal event bus for asynchronous processing; cross‑service events are sent through a message queue (MQ) to decouple services.

Service invocation diagram
Service invocation diagram

Layered Architecture Dependency

Loose layering allows lower‑level entities or services to be accessed directly by upper layers. This can cause:

Leakage of core domain logic.

Difficulty tracking which upper‑layer components depend on a changed lower‑layer service.

Potential for aggregates to bypass the Application layer, leading to tighter coupling.

Strict layering enforces that each layer only provides services to the immediate upper layer:

Domain entities are accessed exclusively through Domain Services.

Domain Services are consumed only by Application Services.

Application Services expose APIs to the Facade (UI) layer.

When a lower‑level service changes, only its direct upper layer needs to be updated, simplifying impact analysis.

Encapsulation of entity methods into Domain Services prevents accidental exposure of business rules.

Loose vs. strict layering
Loose vs. strict layering

Data Object Model

Four object types are used to keep each layer independent:

Persistent Object (PO) : Direct mapping to database tables; used for CRUD operations in the Infrastructure layer.

Domain Object (DO) : Runtime representation of business entities; carries core data and behavior within the Domain and Application layers.

Data Transfer Object (DTO) : Container for data exchanged between the UI layer, Application layer, and external services.

View Object (VO) : Tailored for UI rendering; assembled from DOs/DTOs by the Facade.

Conversion Flow by Layer

Infrastructure layer : Accepts DO as input, converts it to PO for persistence, and converts PO back to DO for output.

Domain layer : Operates directly on DOs; no conversion is needed.

Application layer : Works with DOs. When invoking another microservice, DOs are transformed into DTOs for transport.

User‑Interface (Facade) layer : Receives DTOs from the front‑end, converts them to DOs for the Application layer, and converts resulting DOs to VO for the UI.

This systematic conversion isolates each layer from the concrete representation used by other layers, preserving loose coupling while allowing each layer to work with the most appropriate abstraction.

Data object conversion diagram
Data object conversion diagram

Additional notes on persistence conversion:

For simple CRUD, PO ↔ DO is a one‑to‑one mapping.

When queries require auxiliary fields (e.g., beginTime, endTime), a specialized QueryPO extends the base PO with those fields. The repository returns QueryPO, which is then mapped to DOs.

For read‑only queries where the front‑end and back‑end share the same shape (e.g., name search), the same DTO/DO can be reused to avoid unnecessary conversions, provided the coupling is acceptable for the specific context.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

microservicesDomain-Driven Designservice layering
Thoughts on Knowledge and Action
Written by

Thoughts on Knowledge and Action

Travel together, with knowledge and action all the way

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.