Request and Response cycle in Elixir: Phoenix
By: Siddhant Singh
Tags: Elixir

Phoenix App

Let’s come down to your phoenix app which you’ve just created. When you create a project or type this command:

mix phx.new <project_name>`

It will start the otp_app. So it means when you create your project Elixir is creating an OTP app. I will not get into how OTP works because it’s another big topic in Elixir's world.

To explain this you have to go your mix.exs file and you will see something like this

def application do

[

mod: {Banking.Application, []},

extra_applications: [:logger, :runtime_tools]

]

end

When you run the server using mix phx.server, Elixir starts all the applications listed in the “application” and then it will start your phoenix project. So when I say starting an application, it will call the function name “start” in the module give in ‘mod’.

So when we run the server the start function will get invoked in your application file. So go to your lib/<app-name>/application.ex file you’ll see something like this

def start(_type, _args) do

# List all child processes to be supervised

children = [

# Start the Ecto repository

Banking.Repo,

# Start the endpoint when the application starts

BankingWeb.Endpoint

# Starts a worker by calling: Banking.Worker.start_link(arg)

# {Banking.Worker, arg},

] opts = [strategy: :one_for_one, name: Banking.Supervisor]

Supervisor.start_link(children, opts)

end

This function creates a supervisor process that monitors two-child supervisor processes for Repo and Endpoint. A supervisor process doesn’t do any actual work, rather, it only checks if the child processes are working or dead. Since our start function started two child processes, both of which are supervisors, it also means that these child supervisors have one or more workers or supervisors.

We don’t need to see the Repo supervisor because it’s for managing database connections. Now let’s explore Endpoint supervisor.

defmodule BankingWeb.Endpoint do

use Phoenix.Endpoint, otp_app: :banking



socket "/socket", BankingWeb.UserSocket,

websocket: true,

longpoll: false plug Plug.Static,

at: "/",

from: :banking,

gzip: false,

only: ~w(css fonts images js favicon.ico robots.txt) if code_reloading? do

plug Phoenix.CodeReloader

end plug Plug.RequestId

plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint] plug Plug.Parsers,

parsers: [:urlencoded, :multipart, :json],

pass: ["*/*"],

json_decoder: Phoenix.json_library() plug Plug.MethodOverride

plug Plug.Head plug Plug.Session,

store: :cookie,

key: "_banking_key",

signing_salt: "kSKZtoWp" plug BankingWeb.Router

end

Banking.Endpoint is a child supervisor of the main application in this case Banking is the parent supervisor. You will not see the required start_link function in Endpoint. The line

use Phoenix.Endpoint, otp_app: :banking

is doing a lot of things for you. To get into detail you might have to learn about metaprogramming. Metaprogramming will define the start_link dynamically with all the worker details.

Behind the scene, a lot of things happening which I was not familiar with in starting but when I read about metaprogramming it got me thinking about the functions like ranch. Ranch supervisor is also which is dynamically defined in your phoenix app. This supervisor starts Cowboy process listening at port 4000 on the localhost and is configured to pass all requests to Plug.Cowboy.Handler.