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
snoop
that assigns a key/value pair to the%Plug.Conn{}
struct, inspects the transformed struct, and returns it. For the key/value pair, assign the keyanswer
a value of "Yes", "No", or "Maybe" which you can randomly pick using:answer = ~w(Yes No Maybe) |> Enum.random()
-
Add
snoop
as the final plug in thebrowser
pipeline 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'sassigns
field should include a randomanswer
value 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.