Ports and Adapters

Ports and Adapters, also called Hexagonal Architecture, keeps the application core independent from outside technologies such as web frameworks, databases, queues, file systems, and third-party APIs.

The core idea is simple: the application talks through ports, and adapters translate between those ports and the outside world.

HTTP API      CLI       Message Consumer
  |            |              |
Inbound Adapter Inbound Adapter Inbound Adapter
  |            |              |
          Inbound Ports
              |
        Application Core
              |
          Outbound Ports
  |            |              |
Database   Email API     Payment Gateway
Outbound   Outbound      Outbound
Adapter    Adapter       Adapter

Ports

A port is a boundary contract owned by the application.

Common types:

Ports describe what the application needs or offers without describing how the outside technology works.

Adapters

An adapter connects a port to a real delivery mechanism or external dependency.

Examples:

Adapters are replaceable. The application core should not care whether an order came from HTTP, a background job, or a command line tool.

Dependency Direction

Dependencies point toward the application core.

Adapters -> Ports -> Application Core

The core owns the port interfaces. Infrastructure implements the outbound ports and calls the inbound ports.

This is dependency inversion in practice: business rules define the contracts, and technology details plug into them.

When To Use It

Use Ports and Adapters when:

Avoid overdoing it for very small applications where direct framework code is simpler and unlikely to change.

How It Differs From Clean Architecture

Ports and Adapters and Clean Architecture are closely related. They both protect business rules from external details and use dependency inversion. The difference is mostly emphasis and vocabulary.

Topic Ports and Adapters Clean Architecture
Main metaphor Application core surrounded by ports and adapters. Concentric layers with dependencies pointing inward.
Primary focus Boundaries between the application and the outside world. Layering of enterprise rules, use cases, interfaces, and infrastructure.
Common vocabulary Inbound port, outbound port, adapter, application core. Entity, use case, interface adapter, framework, driver.
External systems Treated as adapters plugged into ports. Usually placed in outer infrastructure/framework layers.
Layer prescription Less prescriptive about internal layers. More explicit about domain, application, interface adapters, and infrastructure.
Testing emphasis Swap real adapters for fake adapters. Test inner layers independently from outer layers.

Practical Difference

In practice, Clean Architecture often uses Ports and Adapters inside its application and infrastructure boundaries.

For example, a .NET Clean Architecture solution might have:

WebApi -> Application -> Domain
Infrastructure -> Application

The Application project defines an outbound port:

public interface IOrderRepository
{
    Task<Order?> GetByIdAsync(Guid id, CancellationToken cancellationToken);
    Task SaveAsync(Order order, CancellationToken cancellationToken);
}

The Infrastructure project provides the adapter:

public sealed class EfOrderRepository : IOrderRepository
{
    private readonly AppDbContext _dbContext;

    public EfOrderRepository(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public Task<Order?> GetByIdAsync(Guid id, CancellationToken cancellationToken)
    {
        return _dbContext.Orders.FindAsync(new object[] { id }, cancellationToken).AsTask();
    }

    public Task SaveAsync(Order order, CancellationToken cancellationToken)
    {
        _dbContext.Orders.Update(order);
        return _dbContext.SaveChangesAsync(cancellationToken);
    }
}

Clean Architecture describes the broader structure. Ports and Adapters describes the boundary mechanism.

Quick Rule

Use this distinction:

References