Hexagonal Architecture in Kotlin: Code Purity and Flexibility

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Hexagonal Architecture in Kotlin: When Code Breathes Freely

\n\n

Imagine you are building a house. You could immediately pour the foundation, erect the walls, and install the windows. Or you could first design the framework, lay the utilities, and only then—finish the interior. In the programming world, the second approach is called hexagonal architecture (also known as Ports & Adapters). And Kotlin, with its conciseness and powerful type system, is the ideal language to bring this concept to life.

\n\n

This article is not a boring textbook. It is a practical guide that will show you how Hexagonal Architecture in Kotlin turns your code into a flexible, testable system independent of external services. We will break down an example from scratch, write real code, and see how it works in practice.

\n\n

What is Hexagonal Architecture and Why Do You Need It?

\n\n

Alistair Cockburn, who coined the term, compared an application to a hexagon. In the center is your business logic. On the edges are ports (interfaces) through which it communicates with the outside world. Adapters are implementations of these interfaces for specific technologies: a database, a web framework, a message queue.

\n\n

The key idea: business logic knows nothing about how data is stored or which framework is used. It simply calls port methods. Want to replace PostgreSQL with MongoDB? Just write a new adapter. The business logic won't even notice the substitution.

\n\n

In Kotlin, this is especially convenient thanks to interfaces with default implementations, sealed classes, and functional style. Let's get down to business.

\n\n

Designing the System: An Online Store Example

\n\n

Let's say we are writing a microservice for order management. At the center is OrderService, which creates orders and checks product availability. The outside world is an HTTP controller and a database.

\n\n

Here is what the project structure looks like:

\n\n
src/\n├── domain/          # Core (business logic)\n│   ├── model/\n│   ├── port/\n│   └── service/\n├── adapter/\n│   ├── input/       # Incoming adapters (controllers)\n│   └── output/      # Outgoing adapters (repositories)\n└── Application.kt   # Entry point\n
\n\n

Step 1. Core: Models and Ports

\n\n

Let's start with the order model. In Kotlin, this will be a data class:

\n\n
// domain/model/Order.kt\ndata class Order(\n    val id: String,\n    val customerId: String,\n    val items: List<OrderItem>,\n    val status: OrderStatus\n)\n\nenum class OrderStatus {\n    PENDING, CONFIRMED, SHIPPED, CANCELLED\n}\n\ndata class OrderItem(\n    val productId: String,\n    val quantity: Int\n)\n
\n\n

Now let's define the ports—interfaces through which the core communicates with the outside world. We will have two ports: one for retrieving product data, and another for saving orders.

\n\n
// domain/port/ProductRepository.kt\ninterface ProductRepository {\n    fun checkAvailability(productId: String, quantity: Int): Boolean\n}\n\n// domain/port/OrderRepository.kt\ninterface OrderRepository {\n    fun save(order: Order): Order\n    fun findById(id: String): Order?\n}\n
\n\n

Notice: there is no mention of a database, HTTP, or frameworks anywhere. Pure business logic.

\n\n

Step 2. Business Service

\n\n

Now let's write OrderService, which uses these ports. In Kotlin, we pass dependencies through the constructor—this is called dependency injection (DI).

\n\n
// domain/service/OrderService.kt\nclass OrderService(\n    private val productRepository: ProductRepository,\n    private val orderRepository: OrderRepository\n) {\n    fun createOrder(customerId: String, items: List<OrderItem>): Order {\n        // Check availability of each product\n        for (item in items) {\n            if (!productRepository.checkA                

Blogs

Book Recommendations