Ports and Adapters: The Hexagonal Core

**Hexagonal Architecture** (also known as **Ports and Adapters**) is an architectural pattern that moves from a layered model to a "centered" model. The goal is to isolate the application's core logic (the Domain) from external concerns—UI, databases, and third-party APIs—by using explicit interfaces (Ports) and implementations (Adapters).

I. The Core Philosophy: Dependency Inversion

In a traditional layered architecture, the Business layer depends on the Data Access layer. Hexagonal Architecture flips this:

* **The Domain is Sovereign:** It defines **Ports** (interfaces) that describe what it needs.

* **Infrastructure is an Implementation Detail:** External systems provide **Adapters** that implement those ports.

II. Anatomy of the Hexagon

1. The Inside: Domain and Ports

The core contains only business logic. It has zero dependencies on frameworks (like Spring) or drivers.

* **Driving Ports (Inbound):** Interfaces defining what the outside can do to the domain (e.g., `PageService.save()`).

* **Driven Ports (Outbound):** Interfaces defining what the domain needs from the outside (e.g., `PageRepository`).

2. The Outside: Adapters

Adapters bridge the gap between the Port and the external technology.

* **Primary Adapters (Driving):** The REST API, the CLI, or the Admin UI. They call the Domain's driving ports.

* **Secondary Adapters (Driven):** The PostgreSQL implementation of a repository, the MailGun implementation of a notification service.

III. Concrete Example: Decoupling Page Storage

In Wikantik, the `PageManager` interface is a **Driven Port**. The engine doesn't care if pages are stored in a Git repo, a database, or a cloud bucket.

The Port (`wikantik-api`)

```java

public interface PageRepository {

void persist(WikiPage page);

Optional<WikiPage> fetch(String id);

}

```

The Adapter (`wikantik-main`)

```java

public class JdbcPageRepository implements PageRepository {

private final JdbcTemplate jdbc; // Implementation detail

@Override

public void persist(WikiPage page) {

jdbc.update("INSERT INTO pages...", page.getId(), page.getContent());

}

}

```

IV. Technical Integrity: Preventing Leakage

A common failure in "Hexagonal" systems is **Framework Leakage**. If your `WikiPage` entity in the core hexagon contains JPA annotations (`@Entity`, `@Table`), you have leaked infrastructure into the domain.

**The Wikantik Standard:**

1. **Pure Entities:** Entities in `wikantik-api` are POJOs or Records with zero annotations.

2. **Mapping Layers:** The Adapter is responsible for mapping Domain Entities to Persistence Entities (e.g., mapping a `WikiPage` to a `PageDbo`).

3. **No Persistence in Domain:** Domain logic never calls `save()` or `commit()`. It returns events or updated state; the Application Service (the driving port implementation) handles the persistence orchestration.

---

**See Also:**

- [Domain Driven Design](DomainDrivenDesign) — How to model the "Inside" of the hexagon.

- [System Architecture](WikantikArchitecture) — The 18-module breakdown of Wikantik.

- [Constructor Injection](ConstructorInjection) — Wiring adapters to ports without coupling.