Folder organization discussion proposal

Hi,

I learned yesterday about Hanami and so far I’m loving it! After seeing that it’s inspired by Uncle Bob’s Clean Architecture I instantly became a fan and intend to start using it in my next projects.

After trying on the beginners tutorial I noticed something that I thought could be improved: the folders’ structure. In the following lecture, Uncle Bob says something that I found really interesting: when you look at a Ruby on Rails folder you instantly know it’s a project developed in Rails. Isn’t it better if you look at the folder structure and instantly know what the project is all about (say a books organizer)?

Of course we shouldn’t just follow blindly everything that Uncle Bob says, but I think it’s nice to discuss it. What do you think about it? Should Hanami be reorganized in such way that features folders are in the root (or say in a “source” folder) and controllers, entities, repositories, templates, views and interactors inside each of them?

I hope this is a good place to put such discussion. I searched for other possibilities, but since it’s more of a philosophical long term issue, I thought this was best.

Best regards,
Victor Aldecoa

@victoraldecoa Thanks for you suggestion. Yes this is the right place where to discuss about it.

We already have lib/ folder where you can add interactors. For me, each interactor maps one-to-one the use cases of a project. By simply looking at lib/bookshelf/interactors you should be able to determine the use cases implemented by a project.

I just stumbled across this topic after brainstorming this idea as well. I think it makes a lot of sense and I’m going to look whether I can tweak my Hanami project to support this. It makes way more sense intuitively IMO. Just to spell out what Victor is suggesting, the project directory would look something like:

apps/web/
  products/
    index/
      partials/
        product/
          product.html.erb
          product.css
      index_action.rb
      index_view.rb
      index.html.erb
      index.css
      index.js
      images/
        an_image.jpg
  customers/
    etc...

So rather than structuring around functionality you structure around features / parts of the application. We don’t mental map an application by functionality and go through, say, each controller one by one, and then each view one by one, and then templates and then assets. We reason about and browse through the application by features / sections of the interface.

The huge benefit from this is it encourages developers to modularize their code and separate their concerns well. As it stands right now, when we categorize by functionality, the boundaries don’t feel clear because there are disparate subdirectories that depend on each other (for example controllers/home/index.rb interacts with views/home/index.rb, as opposed to home/index/index_action.rb and home/index/index_view.html.erb sitting side by side).

If anyone knows of any gotchas I should look out for when I tweak hanami to support this please let me know.

1 Like

Luca and all,

Yes, we have lib for interactors. But not every project uses interactors for all actions, and not every interactor implementation uses lib. By structuring the children of apps/web as use cases (rather than either MVC-type component, or entities (as Matt’s tree suggests), the application structure gives you at least broad hints about what the application does.

I can see where this would be a significant challenge, coming from the current convention-based structure of apps. The convention-following logic would have to adapt, either to something like Matt’s all-in-one-directory approach, or to replicating something like the current controllsers/lib/models/views structure for each apps/web (or apps/whatever) directory.

The benefit as I see it, again, would be at least two-fold: ease of onboarding new team members and getting them to think in terms of the app use cases rather than primarily in terms of the MVC structure; and reuse/extraction. Let’s say you wanted to take all the products-related use cases and extract them to a Gem, because you have (or are about to have) multiple applications that use similar business logic for dealing with your products. By extracting that Gem from apps/web in the proposed revised architecture, you can enforce consistency of entities, repository access, etc more easily and effectively than with the Hanami 1.x architecture. For those coming from a heavy Rails background, such a Gem would smack heavily of Rails engines but, with a more use-case-oriented focus, likely be easier for most junior-/mid-level devs to wrap their head around and contribute to efficiently.

Thoughts?