Hacker News new | ask | show | jobs
by nchi3 1606 days ago
> We use bounded contexts ("modular monolith") with strictly separated concerns.

>because the logic between modules is too intertwined and coupled.

That doesn't sound very modular? If your bounded contexts are intertwined, I don't think they can be considered bounded contexts. A modular monolith would only communicate between contexts through well-defined and non-leaky APIs, and that's the opposite of intertwined.

1 comments

They only communicate through well-defined APIs, and there's a rule that cross-context API calls can only happen in the anti-corruption layer (we use a tool to check it at build time).

What I meant by intertwined (maybe a wrong word, I'm not a native speaker):

1) there's a lot of data/logic dependency between the contexts (i.e. a context in its operation depends on N other contexts), although we at least disallow circular references; it's unfortunately dictated by business rules and I'd like to see contexts to be more isolated and self-contained. Some can say that if a change in the requirements requires to change many contexts at once, maybe it's one fat context after all - and they may be right, but we enjoy the current modularization effort, one big fat module would be far less manageable for us.

2) there're occurrences of temporal coupling; there are synchronous operations that spawn several contexts, with a lot of data flowing back and forth

Now, it's easier to manage it in a monolith, in the same process, because:

1) there are no network trips back and forth in case of complex operations with a lot of data

2) no retry logic in case of network connectivity issues

3) DB connections/locks and other in-memory structures can be reused

4) same codebase, so easier to reason about

Microservices require more care and more complex solutions:

1) distributed transactions are hard

2) eventual consistency is hard

3) the idiom "DB per microservice" makes managing the infrastructure harder

4) deployment is harder (if you have changes in several related contexts, there's only 1 deployment in the monolith as opposed to N deployments of microservices)

5) you have to manage different codebases/repos, can't see the whole picture

6) you have to defend against network connectivity issues, microservice unavailability etc.

7) debugging is harder, you can't just step into another microservice like you do with in-memory modules

8) new devs need to be taught all that

The list can go on and on. So we don't try to make all our modules/contexts into microservices just because we like microservices, we have to substantiate a move to a microservice with proof that it will make development/scalability easier for us, and that the advantages outweigh the disadvantages.