Conn
The "conn" object (abbreviation for connection) plays a critical role in the Phoenix framework.
The conn is an Elixir struct, filled with information regarding a web request.
%Plug.Conn{
adapter: {Plug.Adapters.Cowboy.Conn, req},
host: host,
method: method,
owner: self(),
path_info: split_path(path),
peer: peer,
port: port,
remote_ip: remote_ip,
query_string: qs,
req_headers: headers,
request_path: path,
scheme: scheme(transport)
}
Phoenix passes the conn through a series of pipelines in the order they are defined. Each pipeline performs its necessary functions, returning the modified conn.
A web request begins once a user navigates to a particular URL, for example "/". This triggers the application server (Cowboy) to pass conn to the pipelines defined in Endpoint, Router, Controller, and finally View. Each pipeline is responsible for performing some function(s) and then returning the modified conn to the next pipeline. Remember, data in Elixir is immutable and isn't changed but rather transformed.
Let's look at the "page controller" in a newly generated Phoenix application. The line use MyAppWeb, :controller
is a bit of meta programming that brings in the required controller functionality we'll need. We can define controller actions the same way we define regular Elixir functions. Each controller action will take two arguments, conn and parameters. If the parameters don't exist or are not being used we can simply ignore them by prepending an underscore ( _ ) to the params
argument.
defmodule MyAppWeb.PageController do
use MyAppWeb, :controller
# index action (default)
def index(conn, _params) do
render conn, "index.html"
end
# another way to write the index action (same thing)
def index(conn, _params) do
conn
|> render "index.html"
end
end
Our first action, index
uses a call to render and provides the template we want to display as a string. Phoenix will automatically use the name of the controller, "Page", and search for a "PageView" module and "page" template folder. Inside the "page" template folder it will find and display the "index.html.eex" file if it exists or throw an error if the template is missing.
Note, we could also pass the name of the template as an atom, as in
render :index
.