Build foundations for complex Phoenix Web App using –umbrella option – ELIXIR part II

So, as maybe you get here, i’m playing with Phoenix framework trying to learn how to do web development in Elixir the hard way – i mean bumping my head against any single aspect of both the language and the framework.

And what’s best then have a good practice to start your projects?

This is what i get till now for Phoenix.

Usually a good start in building your new app is to split the original idea into smaller units, each with a single responsibility to carry on. This way it’s easier to maintain and to integrate with new features.
Phoenix give the opportunity to organize the modules under what is called an “umbrella”.

Let’s we have a look on it using mix commands and some lines of code.

The app in my mind is a web page from where you can block some category of people you don’t like on twitter, using their twitter preferencies, in order to nag them – ex. all Trump followers – so i’ll call it nagthem.

  • Creating the app:
$ mix phx.new nagthem --umbrella

Using this command the following directory structure is created:

$ tree nagthem_umbrella/ -d 2 -L 1
nagthem_umbrella/
├── apps
├── _build
├── config
└── deps

As you can see the postfix “_umbrella” is added to the app name passed to the command and there is an “apps” directory.

Intuitively it will contains the app’s modules. In fact right now we will find in it the first two modules that we are used to find creating an app whithout the umbrella option:

$ tree apps/ -d 1 -L 3
apps/
├── nagthem
│   ├── lib
│   │   └── nagthem
│   ├── priv
│   │   └── repo
│   └── test
│   └── support
└── nagthem_web
├── assets
│   ├── css
│   ├── js
│   ├── node_modules
│   ├── static
│   └── vendor
├── lib
│   └── nagthem_web
├── priv
│   ├── gettext
│   └── static
└── test
├── nagthem_web
└── support

But now we have the opportunity to add what we are planning to develop in a very appropriated and ordinated way, submoduling as we need.

I mean, i’m planning to interact with twitter’s api, so i will need an api module to do this, well, after cd into apps, with the command

$mix phx.new api --app api --no-webpack --no-html --no-ecto

Phoenix create for me the right app skeleton (without the need for ecto, that is managed in the nagthem app), wich i can populate later using generators.

App struct is:

$ tree api/ -L 2
api/
├── config
│   ├── config.exs
│   ├── dev.exs
│   ├── prod.exs
│   ├── prod.secret.exs
│   └── test.exs
├── lib
│   ├── api
│   ├── api.ex
│   ├── api_web
│   └── api_web.ex
├── mix.exs
├── priv
│   └── gettext
├── README.md
└── test
├── api_web
├── support
└── test_helper.exs

No a single useless file 🙂

I can do something similar for tha admin module of my app,with command

$mix phx.new admin --app admin --no-ecto

In this case i wanted webpack and templates skeletons, so i didn’t used the –no-webpack option, and the appstruct is:

$ tree admin/ -L 2
admin/
├── assets
│   ├── css
│   ├── js
│   ├── node_modules
│   ├── package.json
│   ├── package-lock.json
│   ├── static
│   ├── vendor
│   └── webpack.config.js
├── config
│   ├── config.exs
│   ├── dev.exs
│   ├── prod.exs
│   ├── prod.secret.exs
│   └── test.exs
├── lib
│   ├── admin
│   ├── admin.ex
│   ├── admin_web
│   └── admin_web.ex
├── mix.exs
├── priv
│   ├── gettext
│   └── static
├── README.md
└── test
├── admin_web
├── support
└── test_helper.exs

And last but not least i can group under the umbrella non-Phoenix app, i mean simple Elixir app, if my module doesn’t need any “web” interaction, for example i’m going to implement authentication in this way, and so with command

$ mix new auth --app auth --sup

the lighter skeleton is used and app struct is

$ tree auth/ -L 2
auth/
├── lib
│   ├── auth
│   └── auth.ex
├── mix.exs
├── README.md
└── test
├── auth_test.exs
└── test_helper.exs

Not bad, isn’t it?

Imo this is reallya good way to start with your project, It shows you the right path, and prevents you from messing up before you even get to the heart of the matter.

Imo they could have copied some of this from Django doing such a thing since before elixir was conceived 🙂

And something similar to django urlpatterns can also be done in order to route your requests and to be sure that certain url is routed to the right module.

I manage to achive this editing the router Phoenix use as default, the one created with the nagthem_web app, and it’s pretty simple.

All you have to do is to specify where to redirect certain urls:

defmodule NaggerWeb.Router do
  use NaggerWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", NaggerWeb do
    pipe_through :browser

    get "/", PageController, :index
  end

  forward "/admin", AdminWeb.Router
  forward "/api", ApiWeb.Router

end

I know this isn’t the only way to achieve this, here you can fine an elegant way using subdomain, but formy need this is enough for now.

That’s all folks, for today. If i can in next weeks i’ll keep you informed into my progress with Elixir 😉

Have a good time

Sergio