Understand plugs in Phoenix

I have two questions in order to help me understand the plug system.

First consider the following code (part of some Controller):

def index(conn, _params) do
  conn
  |> Phoenix.Controller.redirect(to: "/somewhere_else")
  |> render("index.html")
end

I would like to understand what happens in that case : is the render method called ? if not how so ? if yes, why does redirect take over render ?

Second, consider the following:

defmodule ProjectWeb.Controller do
  use ProjectWeb, :controller

  plug somePlug

  def method1(conn, _params) do
    conn
    |> render("page1.html")
  end

  def method1(conn, _params) do
    conn
    |> render("page2.html")
  end
end

If I understand correctly, the plug somePlug will be called before method1 or method2 is called. Is there a way to condition the call of somePlug depending on which method among method1 or method2 is called ?

  1. redirect isn’t a pure function and therefore does send the redirect immediatelly. I’m not sure though if render is called (and probably fails) or if it’s not even called.
  2. e.g. plug somePlug when action in [:method1] this is possible in phoenix controllers specifically.
1 Like

Remember that all a Plug is doing is accepting a %Plug.Conn{} structure and some parameters, then returning a different %Plug.Conn{} with new values in some fields. So in this case, the redirect function will take the conn and [to: "/somewhere_else"] as parameters and return a new conn structure. In this case it sets the response code in that structure to 302, adds a location header to the new structure’s response headers, and sets the response body in the new structure to be some HTML (https://github.com/phoenixframework/phoenix/blob/v1.4.0/lib/phoenix/controller.ex#L392)

Then render gets called with the new conn structure and returns it’s own %Plug.Conn{} structure that is a copy of the one passed in, with the response body fields set to the contents of index.html. At a guess I suspect that it leaves the response code as a 302 and leaves the location header in the response headers. Then when all the plugs unwind, Phoenix looks at the content of the conn structure that got returned and formulates an HTML response for the Cowboy server to return. In this case the response includes a 302 redirect status code, the location header, and the HTML content of index.html in the body.

All a Plug does, however, is “change” some fields in the conn that passes through it and return the new structure.

7 Likes