You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Suppose you have a modulithic app with two modules, A and B. Module B depends on module A but not vice versa; so A is the root of the dependency graph. I'm imagining that this app provides a REST API, though I think an html web app would work just as well for this discussion. And I'm imagining that this app uses Spring Data JPA for persistence.
Suppose module A defines an entity Aardvark and module B defines an entity Ball, which is always owned by some Aardvark i.e. there's a many-to-one relationship. To make this work, module B imports the Aardvark entity from module A.
Now suppose you have a REST endpoint at /aardvarks which is defined by module A and which returns a list of Aardvarks. And suppose you want to be able to filter this list based on whether an Aardvark owns a ball or not.
At the moment, the only sensible way I can think to achieve this is to have a query in module A that somehow references the Ball entity in module B. But... that means that module A has some sort of dependency on module B, after all. So, is this considered acceptable within the spirit of Spring Modulith, or is there some other way to achieve what I want that I haven't spotted yet?
My question above is whether this sort of thing can be handled within the spirit of Spring Modulith. But a more immediate question is whether Spring Modulith would actually allow it i.e. would it raise an error in this sort of case? In my real situation, I've so far been writing my downstream query as a native query, which corresponds to a situation where module A in my example has a SQL dependency on module B's data, but module A's code does not depend on module B's code. I haven't tested this, but I imagine Spring Modulith wouldn't test for a SQL dependency and so wouldn't raise an error. But I guess the situation would be different if I used either Spring Data JPA's repository queries or wrote my query in JPQL. Then, it seems, module A's code would depend on module B's code because e.g. the query code in module A would depend on the hibernate classes in module B. So there would in fact be a circular code dependency between A and B (given that ex hypothesi B's code depends on A's code). Perhaps Modulith would raise an error in this case; but I haven't tested it. It also seems that using an @ApplicationModuleTest in module A would require loading module B, since A's code depends on B's code (assuming that tests haven't already failed because of the circular dependency).
I don't think one can get around this issue by creating an additional module C to integrate A and B because in order to integrate them both in C you would probably need to move almost all of A's and B's classes there. So, ultimately, the only answer seems to be that both module A's code and module B's code need to be located within the same module. And since these sorts of downward dependencies can in principle arise between any dependent modules at any time (i.e. at any time, it might become valuable to your business to be able to filter entities that appear earlier in the dependency chain by their relationship to entities that appear later in the dependency train), the ultimate impetus is to move most of your code into a single module, which tends to undermine the rationale for using Modulith in the first place. (I've been discussing a very simple example here, but to make things more concrete, consider the Spring RestBucks example application and imagine you have drinks and orders in separate modules, with orders downstream from drinks, but then it becomes useful to query drinks based on their number of orders...). Of course, there might still be some occasions where one is sure that one will never need to query an upstream entity based on its relationships with downstream entities - so there might be some occasions when one can safely split an app into a multi-module DAG. But I think the dominant pressure will be to move code into a single module.
I'd be grateful for other's thoughts on this, so please do share with me what you think. Ultimately, I think these sorts of downstream query dependencies are likely to arise in any non-toy example project, so I think it is important to know how to deal with them. I'm afraid I can't currently think of any feasible (or even non-feasible) way to handle them while continuing to use Spring Modulith. (In a previous discussion post I asked for help understanding the DAG requirement within Spring Modulith without wishing to criticise it. But I do think the issue I'm raising here is a serious problem.)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Suppose you have a modulithic app with two modules, A and B. Module B depends on module A but not vice versa; so A is the root of the dependency graph. I'm imagining that this app provides a REST API, though I think an html web app would work just as well for this discussion. And I'm imagining that this app uses Spring Data JPA for persistence.
Suppose module A defines an entity
Aardvark
and module B defines an entityBall
, which is always owned by someAardvark
i.e. there's a many-to-one relationship. To make this work, module B imports theAardvark
entity from module A.Now suppose you have a REST endpoint at
/aardvarks
which is defined by module A and which returns a list ofAardvarks
. And suppose you want to be able to filter this list based on whether anAardvark
owns a ball or not.At the moment, the only sensible way I can think to achieve this is to have a query in module A that somehow references the
Ball
entity in module B. But... that means that module A has some sort of dependency on module B, after all. So, is this considered acceptable within the spirit of Spring Modulith, or is there some other way to achieve what I want that I haven't spotted yet?My question above is whether this sort of thing can be handled within the spirit of Spring Modulith. But a more immediate question is whether Spring Modulith would actually allow it i.e. would it raise an error in this sort of case? In my real situation, I've so far been writing my downstream query as a native query, which corresponds to a situation where module A in my example has a SQL dependency on module B's data, but module A's code does not depend on module B's code. I haven't tested this, but I imagine Spring Modulith wouldn't test for a SQL dependency and so wouldn't raise an error. But I guess the situation would be different if I used either Spring Data JPA's repository queries or wrote my query in JPQL. Then, it seems, module A's code would depend on module B's code because e.g. the query code in module A would depend on the hibernate classes in module B. So there would in fact be a circular code dependency between A and B (given that ex hypothesi B's code depends on A's code). Perhaps Modulith would raise an error in this case; but I haven't tested it. It also seems that using an
@ApplicationModuleTest
in module A would require loading module B, since A's code depends on B's code (assuming that tests haven't already failed because of the circular dependency).I don't think one can get around this issue by creating an additional module C to integrate A and B because in order to integrate them both in C you would probably need to move almost all of A's and B's classes there. So, ultimately, the only answer seems to be that both module A's code and module B's code need to be located within the same module. And since these sorts of downward dependencies can in principle arise between any dependent modules at any time (i.e. at any time, it might become valuable to your business to be able to filter entities that appear earlier in the dependency chain by their relationship to entities that appear later in the dependency train), the ultimate impetus is to move most of your code into a single module, which tends to undermine the rationale for using Modulith in the first place. (I've been discussing a very simple example here, but to make things more concrete, consider the Spring RestBucks example application and imagine you have drinks and orders in separate modules, with orders downstream from drinks, but then it becomes useful to query drinks based on their number of orders...). Of course, there might still be some occasions where one is sure that one will never need to query an upstream entity based on its relationships with downstream entities - so there might be some occasions when one can safely split an app into a multi-module DAG. But I think the dominant pressure will be to move code into a single module.
I'd be grateful for other's thoughts on this, so please do share with me what you think. Ultimately, I think these sorts of downstream query dependencies are likely to arise in any non-toy example project, so I think it is important to know how to deal with them. I'm afraid I can't currently think of any feasible (or even non-feasible) way to handle them while continuing to use Spring Modulith. (In a previous discussion post I asked for help understanding the DAG requirement within Spring Modulith without wishing to criticise it. But I do think the issue I'm raising here is a serious problem.)
Beta Was this translation helpful? Give feedback.
All reactions