kanonk
On structuring and configuring a web application project in Elixir
I’m currently developing a web application and am wondering if I’m heading in the right direction.
I decided to opt for Dave Thomas’ approach, where each application resides in its own directory. And all dependencies between them is linked through path. i.e.:
# mix.exs
defp deps do
[
{:accounts, [path: "../accounts"]},
{:mailer, [path: "../mailer"]},
]
end
And the dependencies are as follows
web
├── mailer (../mailer)
└── accounts (../accounts)
└── db (../db)
First thing I’m unsure of, is the separation between accounts and db. As the project grows and I need a new module, i.e. products. This would be a new dependency of web, and would also be dependent on db.
web
├── mailer (../mailer)
└── accounts (../accounts)
└── db (../db)
└── products (../products)
└── db (../db)
One of the reasons I bought into this method of dependencies is that it strives to make a module reusable. In this case accounts and inventory would not be reusable applications on their own.
- Taking into account the previous statement, is this still a good approach to structure the application, or should it be made simpler?
Another issue I encountered was configuring the application. I want to test each module individually. This leads to many applications needing the same configuration.
I opted for configuring each application within its own folder, and importing it in any of the applications depending on it.
Here is an example of that: accounts loading config from db
# /accounts/config/config.exs
use Mix.Config
import_config "../../db/config/config.exs"
And
# /accounts/config/test.exs
use Mix.Config
import_config "../../db/config/test.exs"
- Would this be considered good practice for configuring a project like this?
Any insights will be appreciated ![]()
Most Liked
jeremyjh
Not everyone agrees, but I think having separate OTP applications applies when your storage or deployment lifecycle differs between the different applications. It does not offer any additional abstraction or information hiding beyond what the module system gives you.
Examples: if your mailer would almost make sense as a third-party or open-source library, or as a component that is developed by a different team in your organization.
Talking about different applications needing access to the same relational database schema I think is misguided; I don’t see a benefit to this.
What we do in our application is having multi-levels of context modules. So Account, Product are contexts, they may have sub-contexts that are more specialized but this is just represented as a normal module tree. Communication across contexts should happen at the root level. If you just look at the modules and functions involved, this is pretty much what you end up with in an umbrella project anyway.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








