Ever since seeing Eileen Uchitelle's RailsWorld 2024 talk, I've struggled with the feeling that discussions of modularity are hampered by a lack of consensus on basic terms.

I wrote a few articles to help sort out my thoughts. The third one is probably the most applicable. https://rossney.net/articles/good-boundaries-make-good-systems/

I'm not writing as an expert or any kind of authority, but I sure would enjoy being part of a conversation that promotes clarity around this topic. Please boost.

#Ruby #Rails #RubyOnRails #Modularity

Good Boundaries Make Good Systems

Good Boundaries Make Good Systems: In this article we will focus on the implications of taking autonomy as our North Star in module design. What are the practical implications? As always, what goes in and what goes out?

I propose four conventions for implementing autonomous modules:

1. Packs/modules are only for domain logic. No controllers, views, or other UI objects allowed.
2. Only coupling between packs/modules should be examined for dependency control (coupling to the UI is expected behavior).
3. Only data objects should be passed to and from packs/modules.
4. Packs/modules must own their own data.

Do you think these make sense? Do you have different ideas? I would love to hear about them.

@dcrossney Interesting ideas. The idea with splitting UI from packs seems to make sense. It makes me think of CQRS. You might be interested in Eventide as well. That community has another take on modularization and autonomy - coming from more of an event sourced angle.

@jacobat

I 💜 Eventide, but they have a strong preference for component-based systems. I would love to work on integrating Eventide (or event sourcing in general) with a modularized monolith system.

I think CQRS also works well with this approach because of the clarity provided by the boundary between UI and domain logic.

@dcrossney How do you imagine a modular monolith and something like Eventide could be integrated? What would you put in the monolith?

@jacobat

If everything were in a monolith, then one or more modules could be responsible for building the tables supporting the views. The first difference is that the UI could call command handlers directly (and receive feedback directly, like validation errors).

I could see running "reactors" to support downstream event handling in the same way that conventional Rails apps run worker queues.

This is all just a thought exercise, but that's the high-level overview I see.

@dcrossney I believe you can still do some validation of commands before handing them off to be processed. At least I don’t see a way to validate for some properties in the components themselves. As components must be able to process commands in isolation there’s a natural limit to how much validation you can do in the component. I think :)