Best practice for directory structure of a larger application?

Just tried it on newly generated project and unfortunately even with some tricks with Path.expand/1 for generating a raw list of directories and files it would end up including _test.exs files anyway as when we pass dir_name to files option whole directory is included. The only workaround I can see for it is to only provide a list of files without directories, but never tried it.

I don’t like to have 2 standards for organizing code (one for app and one for lib), so I’m gonna still have tests in test directory. Also keeping support and all test specific files in test directory when all tests are in lib looks like a workaround for me. If there would be an easy way to merge lib and test directories I may consider give it a try again.

Anyway I believe that grouping everything (except tests) into features is still reasonable for me, so I would definitely consider it in my future projects.

1 Like

I wrote a post where I examined and discussed a few different Elixir project directory structures:

http://blog.brian-underwood.codes/elixir/2020/07/17/structuring-an-elixir+phoenix-app/

The main thing I learned (as has been discussed here) is that Elixir is pretty flexible, so you should do what makes sense. But it’s nice to see how different things are organized.

I’m definitely intrigued by @atomkirk’s project structure, as well!

2 Likes

Your link appears broken, here is a working one Structuring an Elixir+Phoenix App - brian-underwood.blogs

2 Likes

Oh, thank you! I updated my blog recently and I though I had preserved links, but apparently not :confounded:. I’ll have a look at this a bit later

The link is broken again, this one is working: Structuring an Elixir+Phoenix app

About @atomkirk structure, I’m gonna try this!
My motivation is that I struggle as well to find tests.

I’m just not sure about the naming convention, I guess that I might keep the full name inside the structure.
Instead of lib/invoices/controller.ex I might try lib/invoices/invoices_controller.ex
The reason for this is to help while using the alias…

If I’m going to call two controllers (for whatever reason, don’t judge me :stuck_out_tongue_closed_eyes:), in an alias Project.Invoices.Controller and alias Project.Payments.Controller, it would conflict, unless I do only an alias Project.Invoices and call a longer Invoices.Controller.function in the code.

As I understand about MVC it’s all about the separation of concerns in the application layer, and not a folder structure, so I’m good about not having to call folders by MVC names as it doesn’t matter.

I see that Phoenix as a relatively new framework (and Elixir as a whole), ended up not being too much well stablished “good practices” or structures in this way.
Some time ago I’ve asked here about LiveView, reading other people code I saw a lot of people not using controllers and views at all, as there are people that create a LiveView module, call the Model layer directly from it and use the render/1 function instead of calling a view or creating a separate file for the html/view.
Personally it looks a bit messy for me but I’m not really against it.

Again, LiveView is also pretty new and I guess it’s just normal to not have a well stablished “right way” to do it.
(And of course a “right way” doesn’t have to exist)

I’m saying this to say that we could treat directory structure like this as well. Even though the default directory structure just works, we could benefit on exploring other ways of doing that.
I personally can see how a project can benefit from such directory structure, and I agree that it helps and make more sense regarding a domain driven design mindset.