August 28, 2026

arc42

Abstract

I have been working with C4 Model and arc42 software documentation. For quite a while. Combining these two standards is a great way to document your software system. This is especially true as AI assisted coding becomes more commonplace because these provide a template for capturing the requirements of the platform so AI can help with development. The purpose of this post is to share the instructions I have created for using the arc42 template, to demonstrate where the C4 Model diagrams fit in, and to serve as a reference to make using these standards easier.

Disclaimer

This post is solely informative. Critically think before using any information presented. Learn from it but ultimately make your own decisions at your own risk.

My arc42 Instructions


1 - Introduction and goals

REFERENCE 1 - Introduction and Goals | arc42 Documentation

Content. Elevator pitch describing (a) who asked for this system to be created, (b) the high-level business goals the system was created for, i.e. why the system exists, and (c) who uses the system.

1.1 Requirements overview

REFERENCE 1 - Introduction and Goals | arc42 Documentation

Content. A list of the business features of the system. A business feature implements one and only one business process which supports the platform’s underlying business goals.

Motivation. From the end user’s point of view, the features of the system should clearly support business activity.

Form. A table or list with the feature name and a short description. Keep the description as short as possible to optimize readability and avoid redundancy. Optionally associate the feature with a high-level business goal. Optionally refer to requirements documents for each feature.

1.2 Quality goals

REFERENCE 1 - Introduction and Goals | arc42 Documentation

Content. A list of the ISO 25010 quality goals most important to the system.

Motivation. Quality goals influence fundamental architectural decisions to ensure the system operates as expected.

Form. A table or list with the quality goal name and a short criteria statement for meeting the goal. Keep the statement as short as possible to optimize readability and avoid redundancy. Refer to 10 (Quality Requirements). Optionally associate the quality goal with a high-level business goal.

1.3 Stakeholders

REFERENCE 1 - Introduction and Goals | arc42 Documentation

Content. Explicit overview of stakeholders of the system. Stakeholders are all persons, roles or organizations having a stake in the system’s architecture.

Motivation. You should know all parties involved in development of the system or affected by the system. Otherwise, you may get nasty surprises later in the development process. These stakeholders determine the extent and the level of detail of your work and its results.

Form. A table or list with role names, person names, and their expectations with respect to the architecture and its documentation. This can be a simple custom table or a more formal RACI Matrix. Optionally include limited contact information.


2 - Constraints

REFERENCE 2 - Constraints | arc42 Documentation

Content. Constraints are decisions, standards, regulations, or conditions that are outside the control of the team and therefore cannot be changed by the architecture. The system’s architecture must operate within the boundaries defined by these constraints. Constraints may originate from enterprise architecture, security, compliance, legal requirements, organizational policies, existing technology platforms, operational requirements, vendor agreements, or business directives. Add subsections as necessary, grouping constraints together.

Motivation. Architects need to understand which decisions are fixed and which remain open for design. Explicitly documenting constraints helps avoid unnecessary discussions, ensures compliance with organizational and regulatory requirements, and provides context for architectural decisions made elsewhere in this document.

Form. A table or list of constraints that significantly influence the system’s architecture. Include:

  • A concise description of the constraint.
  • The source or owner of the constraint.
  • The impact on the architecture, if not obvious.
  • References to the governing policy, standard, regulation, or other documentation.

Constraints may be grouped into categories which include but are not limited to:

  • Business and organizational
  • Legal and regulatory
  • Security and privacy
  • Enterprise architecture and technology standards
  • Infrastructure and operations
  • Vendor, product, or platform constraints
  • Project and delivery constraints

3 - Context

REFERENCE 3 - Context and scope | arc42 Documentation

Content. Describe the system boundary, its users, and its communication partners. Document the interactions that cross the boundary to clearly show what is inside the system, what is outside it, and how they communicate.

Motivation. A clear understanding of the system boundary and external interactions helps architects and stakeholders identify responsibilities, dependencies, integration requirements, and the impact of change.

3.1 Business context

REFERENCE 1 3 - Context and scope | arc42 Documentation

REFERENCE 2 System context diagram | C4 model

Content. Describe the system from a business perspective by identifying all relevant users and communication partners that interact with the system. Focus on what interactions occur and why they occur.

Motivation. Understanding the business context helps stakeholders share a common view of the system’s responsibilities, boundaries, and dependencies, providing a foundation for architectural decisions.

Form. A diagram — “App Name: Business Context View” — based on the C4 System Context Diagram (REF.2) with an optional table or list include the following:

The short form:

  • Partner System: The name of the partner system.
  • Inputs: Brief description of data coming into the system.
  • Outputs: Brief description of data going out of the system.

The long form:

  • Partner Organization: The name of the company, group, or organization responsible for the partner system.
  • Partner System: The name of the partner system.
  • Data Shared: Short business description of the data being exchanged.
  • Data Format: JSON, XML, CSV, [tab] delimited, Excel, … *( Interface Direction: If the system initiates communication, then outbound. If the partner system initiates communication, then inbound.
  • Transfer Direction: If interface direction is outbound, then either push or pull data from the partner. If the interface direction is inbound, then either send or receive data from the partner. Execution Mode: Manual, scheduled, on-demand, real-time Implementation: The product or standard used to establish communication.

3.2 Technical context

REFERENCE 3 - Context and scope | arc42 Documentation

Content. Describe the system from a technical perspective by identifying how all relevant users and communication partners interact with the system. Focus on the technical communication channels: network components, ports, protocols, networks/vpns, and other connectivity details.

Motivation. Understanding the technical context helps architects, developers, and operations teams identify integration requirements, dependencies, network flows, and security considerations.

Form. A diagram — “App Name: Technical Context View” — showing the system, its communication partners, relevant networking and infrastructure components, and the communication paths between them. Each connection should identify the port and protocol used. (and/or) A table or list including the source component and domain/IP address, matched with the target component, domain/IP address, port, and protocol.


7 - Deployment view

REFERENCE 1 7 - Deployment view | arc42 Documentation

Content. Describe the technical infrastructure used to deploy, execute, and operate the application. This section should identify the deployable application components, the infrastructure on which they run, the deployment patterns used to deploy them, and the resources they depend upon. Together, these views provide a complete understanding of the application’s deployment environment and operational dependencies.

Motivation. Understanding the deployment view helps architects, developers, operations teams, support teams, and other stakeholders understand how the application is deployed and operated. It provides visibility into deployment requirements, infrastructure dependencies, and resource usage, enabling impact analysis, operational support, troubleshooting, disaster recovery planning, and infrastructure governance.

7.1 Deployment overview

REFERENCE 1 7 - Deployment view | arc42 Documentation

REFERENCE 2 Container Diagram | C4 model

Application components

Content. Describe the major application and storage components that make up the system. Application components are independently deployable executables such as applications, services, containers, workers, scheduled processes, web servers, and APIs. Storage components include databases, file systems, object storage, and other persistent data stores. The diagram should show the primary application components and their relationships. Similar components that share the same purpose and deployment pattern (file ETL) may be represented by a single view in the diagram, with the individual components documented in an accompanying table.

Motivation. Knowing the application’s components helps architects, developers, operations teams, and other stakeholders understand how the application is structured, executed, and operated. It provides a high-level view of the major executables, data stores, and interactions that make up the system while avoiding unnecessary implementation detail.

Form. A diagram — “App Name: Application Components View” — based on the C4 Container Diagram (REF.2) with a required, supplemental table which includes the following:

  • Application Component: The name of the component
  • Responsibility: Brief description of what the component does OPTIONAL
  • Deployment Pattern: Reference to a deployment view sub-section containing the deployment pattern details

Component resource mapping

Content. Provide a detailed inventory of resources needed for each deployed application component; list all dependencies required for the component to operate successfully. The inventory should include resource details for all deployment environments. Every component identified in “Application components” should be documented individually, including components that are represented by a single consolidated view in the diagram.

Motivation. Component resource mapping helps architects, developers, operations teams, and support teams understand how individual components are deployed, identify operational dependencies, assess the impact of change, and support troubleshooting and infrastructure planning.

Form. A table which includes the following:

  • Application Component : The name of a deployed part of the application
  • Resource: A business-level description of the resource needed by the building block — File transfer inbox
  • Solution: The service or technology used in the deployment infrastructure for the resource — S3 Bucket
  • “Non-production 1”: The details of the deployment in the 1st level, non-production environment. — acme-fpa-input-dev01. Rename column to match your environment — DEV.
  • “Non-production n”: The details of the deployment in the nth level, non-production environment — acme-fpa-input-test. Rename column to match your environment — TEST.
  • PROD: The details of the deployment in a production environment — acme-fpa-input

7.n “Pattern name” deployment pattern

REFERENCE 1 7 - Deployment view | arc42 Documentation

REFERENCE 2 Deployment Diagram | C4 model

Content. Describe the technical infrastructure required to deploy and run an application component. Multiple components may use this deployment pattern for execution. Rename “Pattern name” to fit the pattern being described — Docker on ECS deployment pattern, NGINX on EC2 deployment pattern, Lambda deployment pattern, RDS deployment pattern.

Motivation. Understanding the technical infrastructure required by each application component helps architects, developers, operations teams, and support teams identify deployment requirements, operational dependencies, and the impact of change. It also provides an inventory of the infrastructure required to successfully deploy the component.

Form. A diagram — “App Name: ‘Pattern name’ Deployment Pattern View” — based on the C4 Deployment Diagram (REF.2). An optional table of supplemental information — CIDER ranges, subnet names, network zones, etc. — may be added as needed.


8 - Crosscutting concepts

REFERENCE 8 - Crosscutting concepts | arc42 Documentation

Content. Describe the architectural practices and technologies used consistently across the application. Crosscutting concerns span multiple components or services and typically include authentication, authorization, logging, distributed tracing, monitoring, file transfer, and error handling. This section should explain the standards, technologies, and patterns used to implement these concerns across the solution.

Motivation. Understanding crosscutting concepts helps stakeholders understand the common technologies and standards used throughout the application. Many of these concepts are driven by enterprise requirements and constraints that all applications must follow.

Form. Organize this section into dedicated subsections for each significant crosscutting concern. Each subsection should describe the purpose of the concern, the technologies used, applicable standards or policies, and how it is implemented throughout the application. Example subsections:

8.1 Authentication 8.2 Authorization 8.3 Logging 8.4 Distributed Tracing 8.5 Monitoring and Alerting 8.6 File Transfer 8.7 Error Handling 8.8 Configuration Management 8.9 Auditing 8.10 Secrets Management 8.11 Data Protection


9 - Architecture decisions

REFERENCE 1 9 - Architecture decisions | arc42 Documentation

REFERENCE 2 JEP 2: JEP Template

Content. Document the significant decisions that affect the system and have a lasting impact on its structure, quality attributes, operations, maintainability, or evolution. Include decisions relating to architecture patterns, technology selection, integration approaches, security design, deployment models, data management, and other choices that meaningfully influence the architecture. Focus on decisions that required evaluation of alternatives and represent deliberate trade-offs.

Motivation. Recording decisions provides a means of collaboration in the decision-making process and transparency for the rationale behind important choices. It helps to avoid revisiting previously resolved discussions, and provides context for interpreting the architecture, managing technical debt, and planning future changes.

Form. Create an Architecture Decision Record (ADR), which is a separate wiki page or document.

The ADR status may be one of:

  • RFC (Request for Comment)
  • Accepted
  • Rejected
  • Superseded
  • Deprecated
  • Abandoned

The ADR content follows the JDK Enhancement Proposal (JEP) document template sections:

  • Summary
  • Goals
  • Non-goals
  • Success metrics [Optional]
  • Motivation
  • Description
  • Alternatives
  • Testing [Optional]
  • Risks and assumptions
  • Dependencies
  • References [Optional]

10 - Quality

REFERENCE 10 - Quality | arc42 Documentation

Content. This section outlines all quality requirements and provides additional detail to what was defined in 1.2 (Quality goals).

Motivation. Quantify quality goals in a specific and measurable way.

10.1 Quality requirements overview

REFERENCE 10 - Quality | arc42 Documentation

Content. This section provides an overview of the system’s quality requirements and defines the measurable criteria used to evaluate important quality attributes. It supplements 1.2 (Quality goals) by specifying concrete requirements and acceptance criteria.

Motivation. Quality goals are often expressed at a high level and may be open to interpretation. This section translates those goals into specific, measurable, and verifiable requirements, ensuring a common understanding among stakeholders and providing a basis for architectural decisions, implementation priorities, and validation activities.

Form. Typically presented as a structured overview or table that maps quality attributes to their corresponding requirements and measurable targets. Detailed descriptions, metrics, constraints, and acceptance criteria may be provided in other documentation and referenced here.

10.2 Quality scenarios

REFERENCE 10 - Quality | arc42 Documentation

Content. Quality scenarios make quality requirements concrete and allow to decide whether they are fulfilled (in the sense of acceptance criteria). Ensure that your scenarios are specific and measurable. Scenarios may be provided in other documentation and referenced here.

Two kinds of scenarios are especially useful:

  1. Usage scenarios (also called application scenarios or use case scenarios) describe the system’s runtime reaction to a certain stimulus. This also includes scenarios that describe the system’s efficiency or performance. Example: The system reacts to a user’s request within one second.
  2. Change scenarios describe the desired effect of a modification or extension of the system or of its immediate environment. Example: Additional functionality is implemented or requirements for a quality attribute change, and the effort or duration of the change is measured.

Motivation. Quality scenarios provide realistic situations that demonstrate how quality attributes should be achieved in practice. They help stakeholders develop a common understanding of expected system behavior, validate architectural decisions, and identify tradeoffs between competing quality goals.

Form. Typical information for detailed scenarios include the following:

The short form:

  • Context/Background: What kind of system or component, what is the environment or situation?
  • Source/Stimulus: Who or what initiates or triggers a behavior, reaction or action.
  • Metric/Acceptance Criteria: A response including a measure or metric

The long form:

  • Scenario ID: A unique identifier for the scenario.
  • Scenario Name: A short, descriptive name for the scenario.
  • Source: The entity (user, system, or event) that initiates the scenario.
  • Stimulus: The triggering event or condition the system must address.
  • Environment: The operational context or condition under which the system experiences the stimulus.
  • Artifact: The building-blocks or other elements of the system affected by the stimulus.
  • Response: The outcome or behavior the system exhibits in reaction to the stimulus.
  • Response Measure: The criteria or metric by which the system’s response is evaluated.

11 - Risks and technical debt

REFERENCE 11 - Risks and technical debt | arc42 Documentation

Content. Documents the potential risks and identified technical debt affecting the system. Highlight architectural concerns, outstanding compromises, and areas requiring future attention to ensure long-term sustainability and success. Roadmap when concerns may be addressed.

11.1 Potential risks

REFERENCE 11 - Risks and technical debt | arc42 Documentation

Content. Known risks that may affect the system’s success, including security vulnerabilities, single points of failure, scalability bottlenecks, and dependencies on external systems beyond the team’s control. These are usually potential things that might go wrong or cause failure if left unaddressed.

Motivation. Documenting potential risks enables the team to proactively identify, assess, and mitigate threats to the system’s success. It supports informed decision-making, improves transparency, and helps ensure that architectural concerns are addressed before they become significant issues.

Form. A table containing the identified risks, with a concise title and description for each entry. Entries may optionally be assigned an identifier for reference within Section 11.3 (Technical roadmap). Include only information necessary to understand and assess the risk, avoiding unnecessary duplication with other sections.

11.2 Identified debt

REFERENCE 11 - Risks and technical debt | arc42 Documentation

Content. Known technical debt affecting the system, including architectural compromises, implementation shortcuts, deferred improvements, outdated technologies, and temporary solutions that have been carried forward. These are identified — things that are known to exist, having negative consequences if remain unresolved.

Motivation. Documenting technical debt provides transparency into architectural compromises and their impact on the system. It helps stakeholders prioritize remediation efforts, manage risk, and make informed decisions about future investments.

Form. A table containing the identified debt, with a concise title and description for each entry. Entries may optionally be assigned an identifier for reference within Section 11.3 (Technical roadmap). Include only information necessary to understand and assess the debt, avoiding unnecessary duplication with other sections.

11.3 Technical roadmap

REFERENCE 11 - Risks and technical debt | arc42 Documentation

Content. Describe the scheduled plan of activities and initiatives intended to address 11.1 (Potential risks), 11.2 (Identified debt), 9 (Architectural Decisions), as well as to evolve the architecture and improve the system over time. The roadmap communicates architectural priorities and direction while avoiding detailed project management or implementation planning.

Motivation. The technical roadmap provides a forward-looking view of how the architecture is expected to evolve. It helps stakeholders understand planned investments, prioritize future work, and track progress toward reducing debt, mitigating risks, and making system improvements.

Form. A table or timeline presenting the planned architectural initiatives, improvements, and remediation activities. Entries should include provide traceability back to identified items and an estimated start and end date.


12 - Glossary

REFERENCE 12 - Glossary | arc42 Documentation

Content. Capture the relevant domain-specific and technical terminology required to understand the architecture documentation. Use acronyms consistently throughout the document as the standard terminology, defining them only one time here.

Motivation. Establish a shared vocabulary by maintaining definitions for important terms, abbreviations, and acronyms.

Form. A table containing a term with its definition. Add additional columns for multiple language translations.


Summary

That’s it, enjoy!

Summary

That’s it, enjoy!

References

Arc42 Documentation. (n.d.). https://docs.arc42.org/home/

C4 Model. (n.d.). https://c4model.com/

ISO 25010. (n.d.). https://iso25000.com/index.php/en/iso-25000-standards/iso-25010

Roos, P. (2025, January 17). The Ultimate Guide to Software Architecture Documentation. workingsoftware.dev. https://www.workingsoftware.dev/software-architecture-documentation-the-ultimate-guide/?utm_source=chatgpt.com

January 07, 2026

Hexagonal Architecture

Abstract

Hexagonal Architecture is a source code architecture pattern; it is a pattern for organizing your platform’s source code. Also known as Ports and Adapters Architecture, it is a software architectural pattern which separates an application’s core business logic (source code) from external systems or technologies such as databases, user interfaces, or third-party services. The goal of Hexagonal Architecture is to make the core business logic source code independent of any external systems, ensuring the source code remains flexible, maintainable, and testable. Alistair Cockburn documented the Hexagonal Architecture (ports and adapters) in a work published in 2005 (Wikipedia). Cockburn stated the intent of the architecture is:

“Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.”

This post summarizes Hexagonal Architecture. It is a guide for those with previous knowledge of this architecture. The roles, responsibilities, and characteristics of each hexagonal layer are described. Finally, an example pattern for organizing your source code is presented.

Disclaimer

This post is solely informative. Critically think before using any information presented. Learn from it but ultimately make your own decisions at your own risk.

Overview

An overview of Hexagonal Architecture is shown in Figure 2.1.

Figure 2.1 – Hexagonal Architecture Overview (Artisan image)

Hexagonal Architecture Overview
Hexagonal Architecture Overview

Framework is the outermost layer and defines which drivers are supported. A driver is a means of communicating with one of the Frameworks. Common drivers are (a) HTTPS & web browser, (b) JMS & messaging, and (c) SFTP & data files. A Framework has one responsibility which is to adopt requests and responses between the driver and the Application.

Application is the middle layer and defines interactions with the Domain. The Application has two responsibilities.

  1. Coordinate Domain operations to fulfill whatever request came in through the Framework. For example, a single request may require the execution of multiple Domain operations, which the Application would coordinate.

  2. Implement Domain interactions with external resources. For example, the Domain may need purchase order data, which the Application is responsibility for getting on the Domain’s behalf. The Domain is indifferent to the implementation details of interactions with external resources, allowing the Application to update as needed; database one day, API the next.

Domain is the core layer and defines the business. The Domain has one responsibility which is to implement business features.

Further information about each hexagonal layer is provided next.

Domain

The Domain is the core hexagon. Its purpose is to implement all business processes and to abstract all external resources (data) needed to accomplish it. The Domain is free of any Framework details (HttpServletRequest, Session, RestTemplate, etc.) and Application details (JDBC, JMS, REST, etc.).

Figure 3.1 – Domain (Artisan image)

Domain
Domain

The Domain IS your application. The scope of the Domain code is the business requirements, and it implements these details. Anything other than this is abstracted by a Domain secondary port - an interface. This interface is later implemented in the Application. For example, to use purchase order data, the Domain defines an interface to abstract its retrieval. This interface is a Domain secondary port. This interface is implemented in the Application by an appropriate means like querying a database, reading a file, or calling an API.

The Domain receives no raw requests from drivers (HTTPS, SFTP, etc.). Domain primary ports are classes which define communication with the Domain without any driver details.

Domain Model

A model based on DDD object types implements the core business logic of the Domain. The following are common, but not an exhaustive list of Domain model objects.

  • Entity. An object that is not defined by its attributes, but rather by a thread of continuity and its identity (i.e. primary key) Example: Most airlines distinguish each seat uniquely on every flight. Each seat is an entity in this context. However, some airlines do not distinguish between every seat; all seats are the same. In this context, a seat is a value object.

  • Value object. An object that contains attributes but has NO identity (i.e. no primary key). They should be treated as immutable. Example: (1) S, M, L, XL, XXL, (2) Red, Green, Blue, and (3) Name. These are values that are part of an entity but are not uniquely identifiable by themselves (i.e. no primary key). A person’s name may be stored as a String or a custom Name inside an Entity. This Name object would be a value object.

  • Aggregate. A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. An aggregate does NOT have its own unique identity (primary key) as it is a collection of separate entities. The aggregate root guarantees the consistency of changes (ACID) being made within the aggregate by defining a transactional boundary for all Entity objects it contains. Example: When you drive a car, you do not have to worry about moving the wheels forward, making the engine combust with spark and fuel, etc.; you are simply driving the car. In this context, the car is an aggregate of several other objects and serves as the aggregate root to all the other systems.

  • Factory. Methods for creating Domain objects should be delegated to a specialized Factory object such that alternative implementations may be easily interchanged. A Factory is for creating in-memory objects, not persistence.

  • Command. A Command is a user-initiated operation which may be rejected or accepted. If REJECTED, then command processing stops and nothing happens. If ACCEPTED, then command processing continues, and a Domain task/operation occurs. In either case (accepted or rejected) a Domain Event may be published.

  • Service. When an operation does not conceptually belong to any object. Following the natural contours of the problem, you can implement these operations in services.

  • Event. A Domain object that defines a Domain event; something that happened in the past. A Domain Event is an event that Domain experts care about.

  • Publisher. Methods for publishing Domain Events should be delegated to a specialized Publisher object such that alternative publication implementations may be easily interchanged. No implementation details are in the Domain. The Application is responsible for implementing (JMS, SFTP, SMTP, etc.) the publication.

  • Repository. Methods for retrieving Domain objects should be delegated to a specialized Repository object such that alternative storage implementations may be easily interchanged. No implementation details are in the Domain. The Application is responsible for implementing (SQL, data file, REST API, etc.) the repository to provide the data.

  • Sender. Methods for sending Domain objects should be delegated to a specialized Sender object such that alternative sending implementations may be easily interchanged. No implementation details are in the Domain. The Application is responsible for implementing (email, SMS) the sender.

Domain Primary Ports

A Domain primary port is an entry point into the Domain. An entry point is any inbound interaction with the Domain by the outer layers, almost always the Application. A Domain primary port has the following characteristics:

  • It is a concrete class.
  • It defines operations used by the Application to interact with the Domain.
  • It is implemented in the Domain by using:
    • Command objects
    • Service objects
  • It is injected into an Application primary adapter.

Figure 3.2.1 – Domain Primary Port UML

Domain Primary Port UML
Domain Primary Port UML

Domain Secondary Ports

A Domain secondary port is an exit point out of the Domain. An exit point is any outbound interaction with external systems or resources. A Domain secondary port has the following characteristics:

  • It is an interface.
  • It defines interactions with an external system or resource such as a database, message broker, file system, API, etc.
  • It is NOT implemented by the Domain.
  • It IS implemented by an Application secondary adapter.
    • There may be multiple implementations.
  • Different implementations should be easy to use.

Figure 3.3.1 – Domain Secondary Port UML

Domain Secondary Port UML
Domain Secondary Port UML

Application

The Application is the hexagon wrapping the Domain. It has two purposes.

  1. Instantiate instances of Domain primary port classes, injecting them as dependencies into Application primary adapters.
  2. Implement the Domain secondary port interfaces as Application secondary adapters. The Domain is indifferent to the implementation details of these interfaces by the Application (database, file, rest, etc.), so long as the implementations fulfill the interface contract.

The Application is free of any Framework details (HttpServletRequest, Session, RestTemplate, etc.).

Figure 4.1 – Application (Artisan image)

Application
Application

Application Primary Adapters

An Application primary adapter instantiates and uses one or more Domain primary port classes to orchestrate and perform Domain-related operations. An Application primary adapter has the following characteristics:

  • It is a class.
  • It is injected with instances of Domain primary ports (classes) which are the entry points into the Domain.
  • It orchestrates the Domain primary ports (classes) to carry out Domain-related operations.

Application Secondary Adapters

An Application secondary adapter implements the Domain secondary port interfaces. How the Application implements the interface is not important to the Domain, provided it adheres to the interface contract. An Application secondary adapter has the following characteristics:

  • It is a class.

  • Implements a Domain secondary port which are the exit points of the Domain. The Application can implement the interface as needed (database, messaging, rest API, file, messaging, etc.).

  • Injected wherever a Domain secondary port is needed.

Application Primary Ports

An Application primary port is like a Domain primary port. An Application primary port is an entry point into the Application. An entry point is any inbound interaction with the Application by the outer layers, typically a Framework. An Application primary port has the following characteristics:

  • It is a concrete class.
  • It is implemented in the Application by using:
    • Command objects
    • Service objects
  • Defines operations used by the Framework to interact with the Application.
  • Translates the Application “language” into the Domain “language”.
  • Injected into a Framework primary adapter.

Framework

The Framework is the hexagon wrapping the Application. Its purpose is to adapt raw requests from drivers (users/HTTP, messages/JMS, files/SFTP, etc) to the Application.

Multiple Frameworks may exist, and they will use the same Application and Domain. For example, a website user and a marketing company both want to see the same data. The website user’s driver will be a web browser which will interact with a Framework capable of returning HTML. The marketing company’s driver will be a REST API which will interact with a different Framework capable of returning JSON. Since both Frameworks use the same Application and Domain, both return the same data.

Figure 5.1 – Frameworks (Artisan image)

Frameworks
Frameworks

Framework Primary Adapters

A Framework primary adapter instantiates and uses one or more Application primary port classes to adapt raw requests from drivers to the “language” of the Application layer. A Framework primary adapter has the following characteristics:

  • It is a class.
  • Injected with instances of Application primary ports which are the entry points into the Application.
  • Translates the raw driver “language” into the Application “language”. Common drivers are (a) HTTPS & web browser, (b) JMS & messaging, and (c) SFTP & data files.

Driver

A Driver exists outside of the hexagon. A Driver communicates with a Framework using a specific protocol and the Framework listens to requests on that protocol.

For example, a Driver can be a JavaScript framework (Angular, React, Vue, etc.) communicating with a Framework by HTTPS. This Framework uses @Path("helloworld") and @GET or @POST (Building RESTful Web Services with Jakarta REST, n.d.) to listen for HTTPS requests. Once an HTTPS request is received by the Framework, it is translated to Application-defined objects and handed off to the Application handler for processing. Multiple Framework projects may exist to support Drivers using different protocols. Common drivers are (a) HTTPS & web browser, (b) JMS & messaging, and (c) SFTP & data files. The different Frameworks hand off processing to the same Application and Domain, allowing access to the same business features.

Figure 6.1 shows this with 4 different raw drivers each supported by their own Framework. All the Frameworks, however, share the Application and Domain.

Figure 6.1 – Drivers (Artisan image)

Drivers
Drivers

Example Source Code Organization

Suppose the ABC Sales Report business feature is needed.

NOTE A feature (aka “business feature”) implements one and only one business process which supports the platform’s underlying business goals.

First, create a new source code repository with the following name:

abc-sales-report

Next, follow the Hexagonal Architecture pattern and create sub-folders based on the hexagon layers. Physically these are file system folders created on the file system inside the repository. Logically these folders have different names depending on the technology you are using. If you are using Java and Maven, you may refer to these folders as modules of a project. If you are using C# and Visual Studio, you may refer to these folders as projects of a solution. For this example, I will refer to them as modules. The names of the modules both identify the hexagon layer the code is related to and declare the intent of the code. For example, abc-sales-report repository may have the following modules:

/abc-sales-report
    /api
    /jms
    /application
    /domain
    /ui

Here is a description of each module:

/api A Hexagonal Architecture Framework module containing REST endpoints. Provides a way the outside world may interact with the Domain. Responsible for translating HTTPS requests into Application objects for processing.

/jms A Hexagonal Architecture Framework module containing messaging Java (JMS) listeners. Provides a way the outside world may interact with the Domain. Responsible for translating Java JMS messages into Application objects for processing.

NOTE You may be asking, “Why not name the module ‘framework’ and put all framework layer code in one module?” Recall from 6.1, there may be many different raw drivers that want to communicate with your platform and each raw driver will use a different protocol for communication. Following Hexagonal Architecture, separate the raw driver protocol handlers into different modules so each module is only responsible for translating its raw driver “language” into the application layer “language”. This is done so that ultimately the Domain can handle processing the request. Each deployment will include the Application and Domain code.

/application A Hexagonal Architecture Application module containing Domain orchestration and Domain secondary port (exit points) interface implementations. These implementations provide a way the Domain may interact with the outside world.

/domain A Hexagonal Architecture Domain module containing the business feature code. This layer should have no knowledge of the Framework or Application code. It should be easily testable without any external runtime environments and easily reusable as Framework or Application layer code is changed.

/ui A UI raw driver. Think single-page application technology like Angular. Responsible for translating user input into HTTPS (typically) to interact with the Framework /api module for requests.

Everything for the abc-sales-report is contained in a single repository. This helps the code adhere to the characteristics of Feature-Oriented (modular) Architecture.

NOTE These characteristics are the same as microservices. However, the word “microservice” is meaningless and its use should be avoided.

These “microservice” characteristics (Ma, medium, 2018) match up with Hexagonal Architecture in the following ways:

  1. Single purpose. The name of the repository is abc-sales-report. The name defines its purpose. If the code is doing anything other than supporting this report, the platform developers got the code wrong.

  2. Loose coupling. The Application code which implements the Domain secondary port (exit points) keeps coupling loose. If not, the platform developers got the code wrong.

  3. High cohesion. If you need to make a change to the ABC Sales Report, it should be clear this repository is the only place you need to go. If not, the system platform developers got the code wrong.

References

Cockburn, A. (n.d.). Hexagonal architecture. Alistair Cockburn. https://alistair.cockburn.us/hexagonal-architecture/. Cockburn’s original post.

Hexagonal architecture. (n.d.). https://fideloper.com/hexagonal-architecture. Description of the hexagon and the responsibilities of each layer.

Ports-And-Adapters. (n.d.). https://www.dossier-andreas.net/software_architecture/ports_and_adapters.html. Definition of primary ports, secondary ports, primary adapters, and secondary adapters.

Jfokus. (2020, February 16). Cubes, hexagons, triangles, and more: Understanding Microservices by Chris Richardson [Video 21:26 - 26:34 (5 minutes)]. YouTube. https://www.youtube.com/watch?v=rMDjuXTQVkk. Chris Richardson’s JFocus 2020 Presentation on Microservices with includes a brief overview of hexagonal architecture.

Wikipedia contributors. (2025, February 18). Domain-driven design. Wikipedia. https://en.wikipedia.org/wiki/Domain-driven_design. Domain driven design (DDD) list of common model object names and responsibilities.

Karol.Kuc. (2020, May 20). Hexagonal Architecture by example - a hands-on introduction. blog.allegro.tech. https://blog.allegro.tech/2020/05/hexagonal-architecture-by-example.html. Practical code example demonstrating package structure, class naming conventions, and how interfaces and implementations get put into the different layers.

Dziadeusz. (n.d.). GitHub - dziadeusz/hexagonal-architecture-by-example. GitHub. https://github.com/dziadeusz/hexagonal-architecture-by-example. Practical code example demonstrating package structure, class naming conventions, and how interfaces and implementations get put into the different layers.

Ma, Xiao. (2018, October 17). Microservice Architecture at Medium. https://medium.engineering/microservice-architecture-at-medium-9c33805eb74f.

Building RESTful Web Services with Jakarta REST :: Jakarta EE Tutorial :: Jakarta EE Documentation. (n.d.). https://jakarta.ee/learn/docs/jakartaee-tutorial/current/websvcs/rest/rest.html