A dummy services that illustrates:
- Ports and Adapters
- Multi-module gradle kotlin dsl
- Guice injection with Ktor
Run ./gradlew clean test
to run all the tests
Create the directory /app/lib/conf
and add a file called 'jwt-secret.conf'
jwt.secret = 1234-1234-1234-1234
Run ./gradlew :app:run
to run the service
This project follows a 'ports and adapters' (a.k.a. hexagonal) architecture and is divided into modules
The centre of the hexagon, contains core business logic.
- Ports
- Classes and functions related to business logic.
- Transport layer concerns, e.g. JSON transformation,
- Frameworks (arguable - but try to avoid)
- Databases (arguable - but lets try to be pure)
Everything outside the hexagon. Nothing related to business logic.
- Ports
- JSON serializers/deserializers
- REST clients
- RabbitMQ senders/receivers (if applicable)
- Framework code, e.g. ktor routes
- DAOs, data layer
- Business logic
The 'ports' layer is the only way 'domain' and 'adapters' interact. It is divided into:
- Provided (by domain)
- Required (by domain
- Nothing
Interfaces (and data classes) implemented by the domain sub-project. The adapter layer uses this to communicate with domain code.
- Interfaces for domain services
- Anything else
Interfaces (and data classes) implemented by the adapters sub-project. The domain layer uses this to communicate with adapter layer.
- Interfaces for remote services, message brokers, repositories, etc.
- Anything else
This layer can see all other layers and is responsible for bootstrapping the running application
- Ports
- Adapters
- Domain
- The 'main method'
- Framework configuration needed to glue the other layers together, e.g. initializing Guice modules
- Build configuration needed to create a deployable service.
- Anything that otherwise fits into the 'ports', 'adapters' or 'domain' buckets