Concept · Architecture & domain modeling

Ports and adapters

Hexagonal architecture: the application defines ports (interfaces) and the outside world plugs in through adapters, so business logic never depends on infrastructure.

3 minhexagonal architectureclean architectureonion architecturedependency rule

Ports and adapters, also called hexagonal architecture, was described by Alistair Cockburn in 2005. The application sits at the centre and talks to everything outside it — users, databases, other services, tests — only through ports, which are interfaces the application defines. Adapters implement those ports for specific technologies.

Two kinds of port

Driving (primary)Driven (secondary)
DirectionThe outside calls the applicationThe application calls the outside
PortThe application's use-case APIAn interface the application needs
Example portPlaceOrder.Execute(ctx, input)OrderRepository, PaymentGateway, Clock
Example adaptersHTTP handler, gRPC server, CLI, queue consumer, a testPostgres repository, Midtrans client, SMTP mailer, in-memory fake

The application's source code imports none of the adapters. Driven adapters import the application to implement its interfaces — that's dependency inversion. A composition root (main in Go) builds the adapters and plugs them in.

text
 HTTP handler ─┐                         ┌─▶ Postgres adapter
 gRPC server  ─┼─▶ [ application core ] ─┼─▶ Payment API adapter
 Test         ─┘    ports on each side   └─▶ In-memory fake (tests)

What it buys

  • Testability. A test is just another driving adapter; plug fakes into the driven ports and test every business rule with no database, network or framework.
  • Multiple entry points. HTTP, gRPC, a batch job and a queue consumer all call the same use case, so rules aren't duplicated.
  • Replaceable infrastructure. Switching database or vendor means writing one new adapter.
  • Deferred decisions. You can build and test the core before choosing a database.

The hexagon shape means nothing in particular; it just leaves room to draw many ports. Clean architecture (Robert Martin) and onion architecture (Jeffrey Palermo) describe the same idea with concentric layers and the rule that source dependencies point only inward.

Costs

Mapping between transport, domain and storage types takes code, and for thin CRUD services with no real logic, the layers protect nothing. Use it where business rules are worth isolating and entry points or dependencies are likely to multiply. See the clean architecture lesson, and test doubles for what to plug into the ports in tests.

Learn it in depth