Subscribe for only $15 to access all of our content

#19: Intro to Function Plugs

Elixir 1.4.2

Phoenix 1.3.0

Plug 1.4.3

View source on GitHub

If you’re building a web application in Elixir you’re using Plug.

According to the docs, Plug is a specification for composable modules between web applications.

At the heart of Plug is the connection, which is represented by the Plug.Conn struct, this contains all the data for a given request.

A plug simply takes a connection struct, and returns a connection struct.

This allow us to take our connection, check and modify it if needed, and pass it down for other plugs to use.

Plugs come in two flavors - functions and modules.

The best way to understand how Plugs work is to build one - so let’s get started.

In our movie app, let’s display the number of movies on every page.

Now in our movie controller we could add logic to get our movie count and add it to every action, but that would create a lot of duplicate code.

Let’s create a function plug that gets our movie total and assigns it to our connection.

First we’ll create a new module called MovieData.

Inside it we’ll import Plug.Connection.

Then we’ll create our function plug named ‘movie_total’.

A function plug takes two arguments, the connection and a set of options. Since we don’t won’t use the options in our function, we can ignore them.

Inside our function we’ll use Plug’s assign function to assign our movie count to the connection.

Let’s start with a default value of 3 to test it out.


defmodule Teacher.MovieData do
  import Plug.Conn

  def movie_total(conn, _opts) do
    assign(conn, :movie_total, 3)


Now let’s go back to our MovieController and include our plug.

We’ll import the MovieData module.

Then we’ll call plug :movie_total.


defmodule TeacherWeb.MovieController do
  import Teacher.MovieData
  plug :movie_total

Now let’s open our “app.html.eex”

And we’ll add a movie total, which we should be able to fetch from the connection’s assigns as “movie_total”.

Template path: lib/teacher_web/templates/layout/app.html.eex

<p>Movie total: <%= @conn.assigns[:movie_total] %></p>

With that let’s start up our server.

$ mix phx.server

And if we open our movie app, we should see the movie total of three displayed.

Great now let’s update our function plug to get the real count from the database.

Back in MovieData we’ll need Ecto.Query’s “from” function so let’s import it.

Then we’ll also need to alias our Repo and Movie modules.

Great with that let’s use and give it a query that gets the count of all movies in our database.

Then we can update the default value with the actual count.


defmodule Teacher.MovieData do
  import Plug.Conn
  import Ecto.Query, only: [from: 2]

  alias Teacher.Repo
  alias TeacherWeb.Movie

  def movie_total(conn, _opts) do
    movie_total = m in Movie, select: count("*"))
    assign(conn, :movie_total, movie_total)


And going back to our browser, we see our movie count is displaying the correct number of movies. And it’s being displayed on each page.

More Episodes

#100: Multiple Room Chat Application

In this episode we’ll build a chat application that has multiple chat rooms. The rooms will be created dynamically from the URL and will use Phoenix Channels to provide realtime functionality.

Watch episode
Alchemist's Edition

#99: OTP backed Web Application Part 2

In part 2 we’ll update our application to allow users to add cryptocurrencies from the UI. Once added, we’ll display the cryptocurrency and update pricing every minute using a GenServer.

Watch episode
Alchemist's Edition

#98: OTP backed Web Application Part 1

In part one of this series we’ll lay the foundation for our application. First we’ll see how we can fetch cryptocurrency prices. Then we’ll create a GenServer to store the prices and add it to our supervision tree.

Watch episode