Building a Web App with Elixir & Phoenix — Part 3

April 27, 2018


Umbrella projects

Unlike other web-based frameworks where functionalities are tightly coupled to the application structure, in Elixir you are encouraged to spilt them into small domains of concerns.

Elixir as an Umbrella project structure that helps you to organise your application into different domains of conerns.

Each Umbrella project is made up of Apps. Ideally what you are trying to achieve is a structure like this:

├── apps
    ├── todoapp
    └── todoweb

Where todoapp is concerned with your business logic and todoweb is concerned with the connections to the outside world.

Let’s try to initialise our umbrella application. In your project folder, run let’s start a new Mix project, but this time with the--umbrella flag.

mix new todo_umbrella --umbrella

This creates a new umbrella project. Next, run

mix --module TodoWeb --no-ecto

This will create a new Phoenix project without Ecto. We want to use Phoenix purely as a web interface for your application and not have it tied to any business logic.

At this point your directory structure should be


We are going to move the dependent applications into the apps folder in your umbrella project. cd to todo_umbrella/apps and mv the files in:

mv path/to/todoapp ./
mv path/to/todoweb ./

This will move the 2 folders into your umbrella application. Now, go to the root folder of todo_umbrella and start a new iex -S mix session:

iex(1)> Application.start(:todoapp)
{:error, {:already_started, :todoapp}}
iex(2)> Application.start(:todoweb)
{:error, {:already_started, :todoweb}}

Magic! Turns out Elixir already has automatically detected your child processes and started them automatically, which is why both are returning :error.

Starting :todoweb won’t actually start a webserver. So try again with

iex -S mix phx.server

This time if you try to go to http://localhost:4000 you’ll see the Phoenix landing page!

Let’s try to display data from your database.

In todoweb_web/controllers/page_controllers.ex, update the index controller to fetch a list of items and assign it to the conn.

defmodule TodoWebWeb.PageController do
  use TodoWebWeb, :controller
  alias TodoApp.{Repo, Item}

  def index(conn, _params) do
    items = Repo.all(Item)
    |> assign(:items, items)
    |> render("index.html")

Let’s try to update the index.html.eex template to show the items on the frontend.

<div class="row marketing">
  <%= for item <- @items do %>
    <%= item.task %>  | Task completed? <%= item.completed %>
  <% end %>

Here, @items refer to the :items assignment you added to the conn. We use Elixir’s list comprehension feature to iterate through the list to display the results. Now go to http://localhost:4000 again and the result:


This concludes the beginner guide to starting an Elixir web application. Starting an application is Elixir is easy and maintaining projects is a breeze.

Like my content? Subscribe to receive tips on software engineering.
© Alvin Ng