Skip to content

Spring Boot

Java · Kotlin · Spring Boot

How is a hexagonal service built when the framework wants to be everywhere?

The most common backend stack, and the one where framework annotations most easily leak into a domain that should not know the framework exists.

The OpenAPI document is written first and registered before the controller exists; server stubs are generated from it. A specification derived from a running controller documents whatever the controller happens to do, including the parts nobody meant to promise.

Acceptance tests through the port with the adapters stubbed, then a thin ring of @SpringBootTest slices for the wiring itself. Testcontainers for the datastore, consumer-driven contract tests for the calls that leave the service.

Ports and adapters with the domain in a module that has no Spring dependency at all — enforced by an ArchUnit rule, not by good intentions. Use case classes as the application boundary; the controller only translates.

Build once, promote the same artefact, configure per environment. Health, readiness and metrics endpoints wired from the start, and observability treated as part of the definition of done.

Job What to use
Acceptance, at the use case port Cucumber-JVM
Contract conformance Microcks, against the deployed provider
Consumer contract pact-jvm
Provider mock in development Microcks
Integration dependencies Testcontainers
Architecture rules ArchUnit
Test quality PIT mutation testing

Why each one, and what it costs: testing tools.

Starter project: arch-blueprint-java · arch-blueprint-kotlin — two sibling repositories in the same workspace already carry this shape, one per language.

The best-supported stack here: the blueprint repositories exist. What is missing is this page walking through them.