First, I would like to thank all of the contributors for the amazing work that went into 2.0! I am salivating at the thought of what 2.1 will bring in full-stack awesomeness!
My proposal here is really just an invitation to open a discussion around how applications will be organized in Hanami 2.1. I first raised this issue in another proposal here.
In that proposal, I asked where mailers and repositories will be placed in 2.0. @jodosha replied that he was leaning towards placing both mailers and repositories in app/. I would like to propose another approach. In doing so, I am hoping to spark a conversation with the core team and other interested users.
I think this is an important issue that is already drawing attention in the community (see e.g., this recent issue: where to put the lib directory of a slice).
For context, a basic Hanami 1.x app is organized like this, with the UI in the
apps directory (with a default
web app), and the business logic in the
lib directory (other objects and directories are omitted for clarity):
A more advanced 1.x app might look something like this, with two apps,
According to @jodosha, one of the problems with the 1.x organizational strategy is that mailers are located in
lib, where they have difficulty utilizing assets that are stored in
Also, there does not seem to be a a prescribed way to “slice” or modularize the business logic in the same way as the UI can be sliced into “apps.”
As @jodosha indicated in his response to my previous proposal, in Hanami 2.0 mailers have been moved to the
app directory. This makes a lot of sense, since mailers are essentially analogous to views and should be part of the UI.
However, since 2.0 does not include a persistence layer, it is not yet clear where repositories will go. The current guide example uses a
lib/bookshelf/persistence directory. Meanwhile, @timriley’s decafsucks example app places the repository in the
app directory, in a
A larger app that follows this example might look like this:
Placing the repository directories in the
app directory creates a number of issues that might make long-term maintenance of Hanami apps difficult.
It commingles persistence objects with UI objects.
It couples repositories to slices, which essentially dictates that business logic be organized along the same seams that divide app slices.
It reduces (eliminates, really) the cohesion of business logic and persistence.
If Hanami is going to reach it’s potential to become a framework that can truly scale from “startup to IPO,” then it must be able to scale from Majestic Monolith to Modular Monolith.
If Hanami apps are going to avoid the middle-age crises that have famously plagued Rails apps that reach a certain size, then there must be a way to “modularize” (in an architectural sense, not the Ruby module sense) the apps’ business logic. This means building into Hanami a way to create vertical boundaries in the business logic, just as we can with slices in the UI.
Such an app might be organized as follows:
The seams in the business logic are free to fall independently from those of the UI.
By keeping related repositories with the business logic module that utilizes them, we improve cohesion and eliminate coupling to other business logic modules or the UI–including stealth coupling through the database layer.
All slices are free to utilize whichever business logic module they need, or multiple ones. In this diagram, the
adminUI might only need the
authmodule, while the
webUI needs to work with both
I apologize if all of this comes across as overly pedantic, but I very keen to see Hanami fulfill all of the promise it has shown. If this promise is to include projects that prioritize scalability and long-term maintainability, then there needs to be a pathway to the Modular Monolith. This proposal may or may not provide the best path, but it is my hope that it will spark some conversation here–the more ideas we can get out into the open for discussion and refinement, the better Hanami 2.1 (and 2.x) will be!