The Pragmatic Studio

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. 👀

  1. 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 key answer a value of "Yes", "No", or "Maybe" which you can randomly pick using:

    answer = ~w(Yes No Maybe) |> Enum.random()
    
  2. Add snoop as the final plug in the browser pipeline defined in the router.

  3. Reload the welcome page and verify that the %Plug.Conn{} struct was written to the server log when the request was processed. The struct's assigns field should include a random answer 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

All course material, including videos and source code, is copyrighted and licensed for individual use only. You may make copies for your own personal use (e.g. on your laptop, on your iPad, on your backup drive). However, you may not transfer ownership or share the material with other people. We make no guarantees that the source code is fit for any purpose. Course material may not be used to create training material, courses, books, and the like. Please support us by encouraging others to purchase their own copies. Thank you!

Copyright © 2005–2024, The Pragmatic Studio. All Rights Reserved.