# Onion Architecture

> Domain model at the center, infrastructure on the outside — like Clean Architecture but with an explicit emphasis on domain services as the second ring.

- **Category**: Software Design
- **Subcategory**: architectural
- **Canonical URL**: https://designpattern.fyi/patterns/onion-architecture/

---

## Description
**Intent**: Protect domain logic from infrastructure details by coupling everything toward the center, never outward.

**Context**: Similar to Clean Architecture but with a stronger emphasis on domain modeling. Your domain services and application logic need to be completely decoupled from database ORM objects, HTTP clients, and third-party SDKs.

**Solution**: Concentric rings, all dependencies point inward:
1. **Domain Model** — core objects, state, and invariants. Pure domain.
2. **Domain Services** — operations spanning multiple domain objects (e.g., a TransferService coordinating Account objects).
3. **Application Services** — coordinates tasks, orchestrates domain services, handles transactions.
4. **Infrastructure** — database implementations, web API controllers, logging, message queues — all implement interfaces defined in inner rings.

Infrastructure depends on the domain. Never the other way around.


## Use Cases
Use when you want the domain model and application logic fully decoupled from infrastructure — particularly when you anticipate swapping databases, message queues, or external services over the system's lifetime.



## Implementation Example

```javascript
// Core Domain
class OrderItem {
  constructor(sku, quantity, price) {
    this.sku = sku;
    this.quantity = quantity;
    this.price = price;
  }
}

// Domain Service interface (implemented in Infrastructure layer)
class PaymentGateway {
  async process(amount) { throw new Error("Not implemented"); }
}

```



## Trade-offs


### Advantages

- Domain core is infrastructure-agnostic and fully unit-testable without any external dependencies.

- Infrastructure details (database choice, messaging system) become implementation decisions, not architectural constraints.




### Considerations & Drawbacks

- Multiple projects or directories with extensive mapping code between layers adds real overhead.

- Teams unfamiliar with ports-and-adapters thinking have a steep learning curve.







