How to handle inter-module dependencies with Elixir?

Hi Everyone,

I’m currently learning Elixir and come mainly from a Java/Typescript background. I’m currently primarily using phoenix, but I think my question is more general and not exclusively related to phoenix.

How does one handle inter-module dependencies in elixir? In phoenix you typically have your “context“ modules that act as something like a service layer for one domain (e.g. User/Article/…), and as far as I am aware, it is common to just call functions from other context modules inside each other.

Coming from languages that have things like interfaces and such, that seems a bit messy and lacks clear domain boundaries. I’m not saying that the way java/typescript do it is better/more correct…

In those languages, I would do something like:

When designing something like a user domain, one can define interfaces that this domain needs… and then use Inversion of Control (dependency injection) to satisfy those dependencies…
E.g., an article domain would need some sort of interface that enables it to load user information…

This makes it clear which capabilities each domain needs to function… and you have a clear overview of the dependencies of that domain. So if, at some point, you would need to move a domain into its own service/application, you would have a clear interface to work with.

How is this done in Elixir? How does one structure elixir applications so that they don’t become a tangled mess where everything is using everything and there are no clear boundaries?

I mean, obviously, there are big elixir projects and somehow they are maintained, so I guess there is some way to manage that… it is probably just a different one from the one with the programming languages I’m familiar with/

It would be great if someone could provide some clarity or could point me to some resources to get a better understanding of architecting Elixir applications

Thanks :slight_smile:

You can use this: Boundary — boundary v0.10.4

1 Like

For inversion of control you’d look at behaviours or protocols in elixir. “Behaviours” switch out behaviour by referencing different modules and protocols switch out behaviour depending on the datatype used. Generally people in elixir are quite pragmatic though and use those when there’s actually the need to switch out behaviour. If there’s just a single way to load users you might just use it.

2 Likes

Never used it but in addition to Boundary there is also this which looks interesting https://www.curiosum.com/blog/introducing-contexted

2 Likes