HoCAT (Hands-on Clean Architecture Template) is a template project based on the principles of Clean Architecture. It provides a production-ready, battle-tested, and evolvable architectural foundation for Java applications, designed to help developers build high-quality, maintainable software systems for the long term.
The core value of HoCAT lies in its clear, decoupled architecture. It is not just a theoretical showcase but a set of engineering practices ready for production use.
For a deeper dive into the engineering decisions, implementation details, and the reasoning behind our technology and tooling choices (such as Gradle conventions and testing strategies), please refer to the HoCAT project's internal documentation: .hocat/README.md.
Theories like Clean Architecture are highly abstract. HoCAT provides an executable, buildable engineering blueprint that translates them into practice. Through its Gradle multi-module structure, it physically enforces architectural dependency rules and answers concrete engineering questions like "how to organize code" and "how to guarantee dependency direction", making abstract theory concrete and actionable.
HoCAT protects the core business logic by enforcing a unidirectional dependency rule, ensuring each component depends only on the bare minimum it needs:
domain: Defines pure business rules, independent of any external frameworks, making it the most stable part of the system.application: Orchestrates business flows, defines Use Cases and Ports, and is also independent of specific technologies.adapter: Implements the interaction logic with external technologies. This is the only place where specific frameworks and tools like Spring Web MVC or Spring Data JPA are introduced.configuration: Assembles the application. It is responsible for introducing the Spring IoC container and wiring the concreteadapterimplementations into theapplication's ports via dependency injection.
This design provides significant flexibility in technology choices. Since adapters are pluggable, you can easily swap implementations. For example, the project provides both adapter/persistence (JPA) and adapter/persistence-jdbc (Spring Data JDBC). You can switch between them with no changes to the business code. Likewise, adapter/web and adapter/web-openapi demonstrate that API implementation strategies are also swappable.
HoCAT adopts a balanced and pragmatic strategy for data transfer between layers, avoiding two common anti-patterns:
- Avoiding a single model that spans all layers: Exposing a database entity directly to the API can leak internal details and create security risks.
- Avoiding a DTO explosion: Creating a separate model for every interaction leads to a proliferation of boilerplate classes and mapping code.
HoCAT's strategy is that each layer owns the data structures for its boundaries. For instance, the web adapter has its own Request/Response models, while the persistence adapter has its persistence entities. This approach maintains clear boundaries without sacrificing developer productivity.
A well-designed adapter should also follow the separation of concerns principle internally. HoCAT isolates third-party library dependencies to the smallest possible scope within an adapter. For example, in the persistence adapter, only a few components, such as entity classes annotated with @Entity (e.g., OrderEntity) and repositories that inherit from Spring Data interfaces (e.g., OrderJpaRepository), are directly coupled with the specific data access technology (like Spring Data JPA). The rest of the adapter remains agnostic to the specific persistence technology, achieving a deeper level of isolation.
For a detailed guide on the architecture design, please refer to the Clean Architecture Implementation Guide (in Chinese).
To understand how the architecture is implemented, here is a tour of the key modules:
- Main Code Modules
domain: Defines the core business entities and rules; the most stable and pure part of the application.application: Orchestrates business logic by defining Use Cases and the interfaces (Ports) that the outer layers must implement.adapter: Connects the application to the outside world by providing concrete implementations for the ports defined in theapplicationlayer.adapter/web: Implements the web interface based on Spring Web MVC, handling HTTP requests.adapter/web-openapi: Implements the web interface based on the OpenAPI specification.adapter/persistence: Implements the data persistence interface based on Spring Data JPA.adapter/persistence-jdbc: Another concrete implementation ofpersistence, using Spring Data JDBC.adapter/client: Implements a client for calling external services.
configuration: The final assembly module. It wires everything together using dependency injection.
- Build Support Directories
buildSrc: Contains custom Gradle build logic for sub-modules.gradle: Contains the Gradle Wrapper and the project dependency version catalog defined in thelibs.versions.tomlfile.scripts: Contains scripts for development and operational support, such as a script to run a stub server for testing.
- Other Directories
docs: Contains project-related documentation, such as architecture diagrams, domain models, and architecture decisions..hocat: Contains the design documents and explanations for the HoCAT project itself, to help understand its architectural decisions.
- Install Java 21
- Install Docker and Docker Compose
Use ./gradlew build to build and test the entire project.
- Use
./gradlew bootRunto run the application locally. - To start the database, run
docker compose up -din theconfigurationdirectory. You can check the dynamically assigned port withdocker compose ps. - To start local third-party services for contract testing, run
scripts/run-stub-runner-server configuration/src/test/resources/contracts/client 16581.
Use ./gradlew bootBuildImage to build a Docker image.
- Formatter: Install the Spotless IDE plugin to auto-format code.
- Foundation: Java 21, Spring Boot 3.5, Spring Bean Validation, Lombok
- Build: Gradle, JaCoCo, Spotless
- Optional Adapters
- Web Adapter: Spring Web MVC, Spring Security, Spring Cloud Contract
- OpenAPI-based Web Adapter: OpenAPI Generator, Spring Web MVC, Spring Security
- Persistence (JPA): Spring Data JPA, MySQL 8, Flyway, Spring Boot Docker Compose Support
- Persistence (JDBC): Spring Data JDBC, MySQL 8, Flyway, Spring Boot Docker Compose Support
- Client Adapter: Spring RestClient, Spring Cloud Contract Stub Runner
- Testing: JUnit 5, AssertJ, Mockito
- Documentation: Markdown, PlantUML
- HoCATLing: A simplified, single-module version of HoCAT, suitable for smaller projects.