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