This is a simple book service that gives you book information.
The project uses a hexagonal architecture and uses the Gradle multi-module way to enforce the architecture by stopping dependencies from the adapter layer entering into the application layer and also stopping dependencies from the application layer entering into the domain layer.
- Java 11+
- Gradle
./gradlew bootR
- Starts up the Spring Boot application../gradlew clean build
- Builds the application including running integration + unit tests.http://localhost:8080/swagger-ui/index.html
- Swagger UI which shows the application API endpoints.
The main goal of this architecture is to abstract(loosely-couple) your business logic from external technologies or frameworks and their rules through the use of ports and adapters. These interfaces define the inputs and outputs of your application but most importantly they are the gateway for anything external to interact with the business logic or the hexagonal.
Below is a visual representation of the hexagonal architecture:
Using packages and modules, such as Gradle Modules, to build an application based on the Hexagonal Architecture , each have their own advantages and disadvantages.
With Packages:
Pros:
Simplicity:
Using packages is straightforward and doesn't require additional tools or configuration. It's a native way of organizing code in many programming languages.Ease of Use:
Developers are already familiar with packages, as they are a fundamental part of most programming languages. There's no need for them to learn a new tool or framework for managing modules.Flexibility:
Packages allow for a flexible organization of code. You can decide on your package structure based on the needs of your application.Compatibility:
Packages work well with most development environments and tools, making it easier to integrate with existing workflows.Cons:
Limited Encapsulation:
Packages may not provide as strong encapsulation as modules. In some languages, classes within the same package can access each other's internals, which can lead to accidental violations of architectural boundaries.Dependency Management:
It can be challenging to manage dependencies between packages, especially in large and complex applications. Ensuring that dependencies flow in the correct direction can require careful discipline.Tooling:
Some languages and development ecosystems may not provide strong tooling for enforcing architectural constraints when using packages alone.Using Modules (e.g., Gradle Modules):
Pros:
Strong Encapsulation:
Modules often provide stronger encapsulation, allowing you to explicitly specify which classes and packages are accessible from outside the module. This can help enforce architectural boundaries more rigorously.Dependency Management:
Modules typically have more advanced dependency management capabilities, allowing you to explicitly declare module dependencies. This can make it easier to ensure that dependencies follow architectural rules.Isolation:
Modules can be built and tested independently, promoting isolation and better separation of concerns. This can lead to more modular and maintainable code.Tooling:
Some build tools, like Gradle, offer powerful module management and build capabilities, which can be useful for large-scale applications.Cons: