Thank you!!
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!
Summary
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).
Hanami 1.x Simple App
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):
Hanami 1.x Advanced App
A more advanced 1.x app might look something like this, with two apps, web
and admin
:
Discussion of 1.x
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 apps
.
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.”
Hanami 2.0
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 repo.rb
file.
A larger app that follows this example might look like this:
Problems with this Approach
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.
A Modest Proposal
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:
Advantages
-
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
admin
UI might only need theauth
module, while theweb
UI needs to work with bothauth
andlending
.
Conclusion
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!
Thank you!