khaledh

khaledh

Discussion about domain-orientated folder structures in Phoenix

Continuing the discussion from Domain-oriented web folder structure:

Essentially:

hello_web
├── controllers
│   ├── foo_controller.ex
│   ├── bar_controller.ex
├── templates
│   ├── foo
│   │   ├── index.html.eex
│   │   ├── ...
│   ├── bar
│   │   ├── index.html.eex
│   │   ├── ...
├── views
│   ├── foo_view.ex
│   ├── bar_view.ex

to:

hello_web
├── foo
│   ├── foo_controller.ex
│   ├── foo_view.ex
│   ├── templates
│   │   ├── index.html.eex
│   │   ├── ...
├── bar
│   ├── bar_controller.ex
│   ├── bar_view.ex
│   ├── templates
│   │   ├── index.html.eex
│   │   ├── ...

I hope @chrismccord will consider making this easier in a future release :slight_smile:

Most Liked

sasajuric

sasajuric

Author of Elixir In Action

I think this is a very good argument!

The question is is it better to have e.g. UserController and TaskController in the same folder, or would it be better to have UserController, UserView, and corresponding templates in the same folder? I currently can’t see much benefits of the former approach, and I can confirm that I’m occasionally annoyed by the current folder structure when working on the web part. I frequently find I need to navigate between separate folders, which is a bit distracting.

In my experience, most often I need to make changes to all the three aspects of a single entity (e.g. a User), so it seems that grouping per entity would work better for the most cases I’ve seen.

Personally, I’ll think about trying out the alternative approach in my next project.

chrismccord

chrismccord

Creator of Phoenix

An option to phx.new would provide two ways of doing the exact same thing, which actually could harm newcomers with an unnecessary choice. Our goals with Phoenix defaults have always been sane defaults that are easily customized for those that require it. Wrt to DDD, we treat the the web as the domain. Grouping templates, views, and controllers is file organization, which the proposed alternative is just fine, but not something the Phoenix team views as preferable. But the point is there is nothing special about our defaults, and to achieve your own desires you can use the same options we use to ship our own out-of-the-box behaviour.

10
Post #4
chrismccord

chrismccord

Creator of Phoenix

I think we actually agree on this point:

Phoenix is indeed only the web interface to your application. The Tasks and UserManagement contexts would live outside of app_web/.

This would be true if we encouraged users to write their application and web code together, such as app/user_management/controller.ex|user_management.ex, but this would directly couple app code and web code together. If we agree the Phoenix is the delivery mechanism to your application, then it absolutely makes sense to group controllers together, because we are only concerned with dispatching web requests into our application, and converting the results into responses.

For example, if we look at the web directory structure of such an app:

app_web
  controllers
    user_controller.ex
    task_controller.ex
    api
      v1
        task_controller.ex
    resolvers
      task_resolver.ex

It passes the test of screaming its intent, within the context of The Web. We are translating user and tasks requests into responses. Those controllers may hook into entirely decoupled parts of our application. With a glance, I can immediately see what the web layer is responsible for, down to handling user requests, a JSON an API, and servicing graphql clients for tasks. If the app had grouped the directories per user/task, I would need to hunt down what the web story actually looks like.

So for me our defaults encourage better application design exactly because the web side is only focused on being the delivery mechanism. Of course we don’t force this on folks and you are free to structure your directories as you see fit :slight_smile:

Hopefully that gives insight to our dir structure.

Where Next?

Popular in Discussions Top

PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
andre1sk
A big advantage to Elixir is all the distributed goodness but for many applications running on multiple nodes having integrated Etcd, Zoo...
New
WildYorkies
It seems that the more I read, the more I find Elixir users speaking about all the ways that Elixir is not good for x, y, and z use cases...
New
blackode
Elixir Upgrading is so Simple in Ubuntu and It worked for me Ubuntu 16.04 git clone https://github.com/elixir-lang/elixir.git cd elixir...
New
cvkmohan
The upcoming Phoenix 1.6 release looks very interesting. Became a habit to watch the commits - and - what they are bringing in. phx.gen...
New
laiboonh
Hi all, I am trying to convince my team to use liveview over the current react. What are some of the points where one should consider us...
New
fireproofsocks
I’ve been working on an Elixir project that has required a lot of scripting. I usually reach for Elixir because I like it more (and in th...
New
sergio
There’s a new TIOBE index report that came out that shows Elixir is still not in the top 50 used languages. It also goes on to call Elix...
New
joeerl
I’m playing with Elixir - It’s fun. I think @rvirding does give Elixir courses these days. Re: files and database - when I given Erlang ...
New
fireproofsocks
This is more of a general question, but I’m wondering how other people in the community think about the pattern matching in function sign...
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48475 226
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42158 114
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New

We're in Beta

About us Mission Statement