This post describes the steps that a HTTP request/response takes in a Phoenix Framework application. The example application described here was generated using the command
mix phoenix.new hello_world.
The steps in the HTTP request/response cycle are outlined as follows:
- HTTP Request
- Phoenix Endpoint
- Phoenix Router
- Phoenix Controller
- Phoenix View
- Phoenix Template
- Phoenix Endpoint
- HTTP Response
A browser user sends an HTTP GET request to
The request is received by the Cowboy server.
Cowboy is an Erlang based HTTP server which is currently the only server with a Plug adapter implemented.
Cowboy will parse the HTTP request and the first Plug Connection will be created in Plug’s Cowboy adapter.
Plug is a web server interface for Elixir that provides a way to compose modules in a sequence during a request/response cycle.
Each plug module receives the HTTP request which is called a Plug Connection and often referred to as the variable
conn. The plug may transform and update the connection and then return an HTTP response immediately or pass the connection to the next plug in the sequence.
The Plug library has built in plugs that provide CSRF protection, sessions, logging, serving static files, and more.
Phoenix applications themselves are built by composing a series of plugs which are defined in a Phoenix Endpoint.
The Phoenix Endpoint is found in the project file
lib/hello_world/endpoint.ex. The endpoint defines the plugs that will make up your application. It is the entry and exit point to the Phoenix application.
Each plug will be called in order as defined in the
HelloWorld.Endpoint. A plug such as the
Plug.Static plug may send a response before the connection is seen by other plugs. Note that the last plug defined is the router.
A Router defines an application’s pipelines and paths. If the given URL path matches based on the HTTP verb and path, the indicated controller action will be run.
Pipelines are defined using the
pipeline macro which describes a sequence of plugs to run on the connection. The
scope macros define which pipelines to run using the
In this example, our GET request to
http://localhost:4000/ will match
get "/" definition so the
PageController.index function will be called after the
:browser pipeline plugs are called with the connection. The
:browser pipeline is called because the
get "/" is defined inside a scope that specifies a pipeline using
The Phoenix Router is analogous to the
routes.rb file in Ruby on Rails. The
mix phoenix.routes command will list the routes and path helpers defined by the router.
The controller is where application logic is done. Often this will include running SQL queries using the
Ecto database library which is not covered in this article.
The params variable will contain a string keyed map of request parameters. Next,
Phoenix.Controller.render/2 is called with the
conn and template name
Phoenix.Controller.render/3 will be called with additional data to render like this:
render conn, "index.html", [data: "data"].
Phoenix.Controller.render/2 method will lookup the template file which by convention should be located in
web/templates/page/index.html.eex and will then call the
Aside from rendering the template, the view also can provide helper functions and path helpers which will automatically be available to the template.
By default, an html formatted EEx template was generated. EEx means Embedded Elixir which allows Elixir code to be included in template files.
index.html.eex file that was generated only contains html by default. So, an alternative template example is shown here.
After the view renders the template, the controller will then call the Plug
send_resp method with the rendered template data to return the HTTP response.
The user receives the rendered template in the browser.