Comments on: Hexagonal Architecture with Java – Tutorial https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/ Mon, 05 May 2025 18:57:16 +0000 hourly 1 By: Dave https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-41210 Wed, 30 Apr 2025 09:03:16 +0000 https://www.happycoders.eu/?p=36898#comment-41210 Should the service not exists in the adapter layer?

]]>
By: Khan https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-40559 Sat, 29 Mar 2025 13:07:49 +0000 https://www.happycoders.eu/?p=36898#comment-40559 Thank you for sharing.

Regarding the point that the REST Adapter has a unidirectional source code dependency on the Application, while the Application does not have any source code dependencies on the outer layers, I'm puzzled about how to handle the following scenarios:

1.Complex conditional queries and pagination information: How can these query conditions and pagination details be passed from the REST Adapter to the persistence layer?

2.A single large form submission from the user: This form may involve multiple business entities, requiring it to be split into different business entities for processing and persistence according to business rules. Does this large form correspond to the WebModel in the example (for instance, a parameter in the Controller marked with the @RequestBody annotation)? Does the Application layer need to establish a "pseudo" domain object identical to this WebModel to receive and handle this request?

]]>
By: Sven Woltmann https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35908 Mon, 21 Oct 2024 08:28:12 +0000 https://www.happycoders.eu/?p=36898#comment-35908 In reply to Sergii Poltorak.

I tried that, but it was complaining about the bootstrap module calling the constructurs and the tests accessing basically any other code. So I eventually decided to write this custom ArchUnit test.

]]>
By: Sergii Poltorak https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35756 Tue, 15 Oct 2024 22:20:48 +0000 https://www.happycoders.eu/?p=36898#comment-35756 In `DependencyRuleTest` I would use `onionArchitecture()` static method from ArchUnit to define models, services, ports, and then verify hexahonal architecture.

]]>
By: Sven Woltmann https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35123 Mon, 30 Sep 2024 08:02:34 +0000 https://www.happycoders.eu/?p=36898#comment-35123 In reply to Kauan Mocelin.

Hi Kauan,

thanks for your message! And you are absolutely right, it this example, one could change the code as follows:

throw clientErrorException(Response.Status.BAD_REQUEST, e.getMessage());

It depends a bit on the type of application. The business layer could throw an exception with very technical terms, and you might want to translate that to a customer-friendly message in the controller.

Or in an international application, the business layer might throw an English error message, and you might want to send localized error messages to the customer.

There's no single right solution :-)

Best wishes
Sven

]]>
By: Sven Woltmann https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35122 Mon, 30 Sep 2024 07:57:13 +0000 https://www.happycoders.eu/?p=36898#comment-35122 In reply to Kauan Mocelin.

This is true if you have, for example, different subdomains in your modules.

But in this article, I use modules for the layers of a _single_ hexagonal application. These cannot be pulled into separate microservices.

]]>
By: Sven Woltmann https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35121 Mon, 30 Sep 2024 07:53:17 +0000 https://www.happycoders.eu/?p=36898#comment-35121 In reply to John.

Hello John,

I use PlantUML: https://plantuml.com/en/.

There is also a PlantUML plugin for IntelliJ, so you can easily add PlantUML files to your projects and render them directly in IntelliJ.

You can find the files I used to create the images in this article in the `docs` folder of the GitHub repo: https://github.com/SvenWoltmann/hexagonal-architecture-java/tree/main/doc

Best wishes
Sven

]]>
By: Sven Woltmann https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35120 Mon, 30 Sep 2024 07:48:41 +0000 https://www.happycoders.eu/?p=36898#comment-35120 In reply to Tophe.

Hello Tophe,

if your architecture works for you, by all means go for it. The hexagonal architecture doesn't dictate what technologies to use to enforce the rules.

What I like about modules is that they force me to think about where to put a new class. If you put it in the wrong module, you either can't reach it from where you want to reach it... or you can't reach other classes from the new class. With modules you get this feedback immediately, with ArchUnit only when you run the tests.

I also like the double protection, especially when you're working in larger teams. If there is only one level of protection, e.g. only ArchUnit, developers are easily tempted to soften a rule. With two levels, the hurdle is much bigger.

Best wishes
Sven

]]>
By: Kauan Mocelin https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35105 Sun, 29 Sep 2024 21:32:39 +0000 https://www.happycoders.eu/?p=36898#comment-35105 In reply to Tophe.

Tophe, on my point of view, modules are a way to turn your codebase "ready" for microservices if need it.

]]>
By: Kauan Mocelin https://www.happycoders.eu/software-craftsmanship/hexagonal-architecture-java/#comment-35104 Sun, 29 Sep 2024 21:29:59 +0000 https://www.happycoders.eu/?p=36898#comment-35104 Hello Sven, congratulations to this tutorial about hexagonal architecture, your didactics are crystal clear and very easy to understand.

I have one doubt: on "CartLineItem.increaseQuantityBy" you throw a "NotEnoughItemsInStockException" with a clear message. So, on "AddToCartController" your rewrite that message:
"throw clientErrorException(Response.Status.BAD_REQUEST, "Only %d items in stock".formatted(e.itemsInStock()));"

Why don't you just reuse the message from model?

Keep going, regards!

]]>