Routes, Plugs, and Pipelines
Notes & Exercises
Code Snapshot
A snapshot of the code at the end of the video is in the raffley/03-plugs-pipelines directory of the code bundle.
Recap: Request Processing
Module Plugs
As we said, plugs come in two flavors: function plugs and module plugs. 🍦
To recap, a function plug accepts a %Plug.Conn{} struct and a list of options, transforms the conn struct or checks for something in it, and returns the updated conn struct:
def my_plug(conn, opts) do
# transforms `conn` or checks for something in it
conn
end
By comparison, a module plug is any module that defines two functions: init/1 and call/2, like this:
defmodule MyPlug do
def init(opts) do
opts
end
def call(conn, opts) do
# transforms `conn` or checks for something in it
conn
end
end
The init/1 function accepts a list of options which it can transform, or simply pass through unchanged. The value returned by init/1 is then passed to call/2 along with the %Plug.Conn{} struct. It's in call/2 that you transform the %Plug.Conn{} struct or check for something in it. In this way, call/2 is just a function plug.
Since init/1 is invoked at compile time and call/2 is invoked at runtime, you can perform relatively expensive operations in init/1 to initialize the options without a penalty at runtime when call/2 is invoked.
Exercise
Snoop on each request as it flows through the HTTP request pipeline of your heads_up app. 👀
-
Write a plug function named
snoopthat assigns a key/value pair to the%Plug.Conn{}struct, inspects the transformed struct, and returns it. For the key/value pair, assign the keyanswera value of "Yes", "No", or "Maybe" which you can randomly pick using:answer = ~w(Yes No Maybe) |> Enum.random()
-
Add
snoopas the final plug in thebrowserpipeline defined in the router. -
Reload the welcome page and verify that the
%Plug.Conn{}struct was written to the server log when the request was processed. The struct'sassignsfield should include a randomanswervalue that we'll use a bit later on.
Solution
The solution for the exercise is in the heads_up/03-plugs-pipelines directory of the code bundle.
📚 Dive Deeper
-
See the offical docs for more details about the %Plug.Conn{} struct.
-
See more details on scope/2, pipeline/2, and pipe_through/1.

