Phoenix v1.3.0 Phoenix.Endpoint behaviour View Source
Defines a Phoenix endpoint.
The endpoint is the boundary where all requests to your web application start. It is also the interface your application provides to the underlying web servers.
Overall, an endpoint has three responsibilities:
to provide a wrapper for starting and stopping the endpoint as part of a supervision tree;
to define an initial plug pipeline for requests to pass through;
to host web specific configuration for your application.
Endpoints
An endpoint is simply a module defined with the help
of Phoenix.Endpoint
. If you have used the mix phx.new
generator, an endpoint was automatically generated as
part of your application:
defmodule YourApp.Endpoint do
use Phoenix.Endpoint, otp_app: :your_app
# plug ...
# plug ...
plug YourApp.Router
end
Endpoints must be explicitly started as part of your application supervision tree. Endpoints are added by default to the supervision tree in generated applications. Endpoints can be added to the supervision tree as follows:
supervisor(YourApp.Endpoint, [])
Endpoint configuration
All endpoints are configured in your application environment. For example:
config :your_app, YourApp.Endpoint,
secret_key_base: "kjoy3o1zeidquwy1398juxzldjlksahdk3"
Endpoint configuration is split into two categories. Compile-time configuration means the configuration is read during compilation and changing it at runtime has no effect. The compile-time configuration is mostly related to error handling and instrumentation.
Runtime configuration, instead, is accessed during or
after your application is started and can be read through the
config/2
function:
YourApp.Endpoint.config(:port)
YourApp.Endpoint.config(:some_config, :default_value)
Dynamic configuration
For dynamically configuring the endpoint, such as loading data
from environment variables or configuration files, Phoenix invokes
the init/2
callback on the endpoint, passing a :supervivsor
atom as first argument and the endpoint configuration as second.
All of Phoenix configuration, except the Compile-time configuration
below can be set dynamically from the init/2
callback.
Compile-time configuration
:code_reloader
- whentrue
, enables code reloading functionality:debug_errors
- whentrue
, usesPlug.Debugger
functionality for debugging failures in the application. Recommended to be set totrue
only in development as it allows listing of the application source code during debugging. Defaults tofalse
.:render_errors
- responsible for rendering templates whenever there is a failure in the application. For example, if the application crashes with a 500 error during a HTML request,render("500.html", assigns)
will be called in the view given to:render_errors
. Defaults to:[view: MyApp.ErrorView, accepts: ~w(html), layout: false]
The default format is used when none is set in the connection.
:instrumenters
- a list of instrumenter modules whose callbacks will be fired on instrumentation events. Read more on instrumentation in the “Instrumentation” section below.
Runtime configuration
:cache_static_manifest
- a path to a json manifest file that contains static files and their digested version. This is typically set to “priv/static/cache_manifest.json” which is the file automatically generated bymix phx.digest
.:check_origin
- configure transports to check origins or not. May be false, true or a list of hosts that are allowed. Hosts also support wildcards. For example:check_origin: ["//phoenixframework.org", "//*.example.com"]
:http
- the configuration for the HTTP server. Currently uses Cowboy and accepts all options as defined byPlug.Adapters.Cowboy
. Defaults tofalse
.:https
- the configuration for the HTTPS server. Currently uses Cowboy and accepts all options as defined byPlug.Adapters.Cowboy
. Defaults tofalse
.:force_ssl
- ensures no data is ever sent via HTTP, always redirecting to HTTPS. It expects a list of options which are forwarded toPlug.SSL
. By default it sets the “strict-transport-security” header in HTTPS requests, forcing browsers to always use HTTPS. If an unsafe request (HTTP) is sent, it redirects to the HTTPS version using the:host
specified in the:url
configuration. To dynamically redirect to thehost
of the current request,:host
must be setnil
.:secret_key_base
- a secret key used as a base to generate secrets for encrypting and signing data. For example, cookies and tokens are signed by default, but they may also be encrypted if desired. Defaults tonil
as it must be set per application.:server
- whentrue
, starts the web server when the endpoint supervision tree starts. Defaults tofalse
. Themix phx.server
task automatically sets this totrue
.:url
- configuration for generating URLs throughout the app. Accepts the:host
,:scheme
,:path
and:port
options. All keys except:path
can be changed at runtime. Defaults to:[host: "localhost", path: "/"]
The
:port
option requires either an integer, string, or{:system, "ENV_VAR"}
. When given a tuple like{:system, "PORT"}
, the port will be referenced fromSystem.get_env("PORT")
at runtime as a workaround for releases where environment specific information is loaded only at compile-time.The
:host
option requires a string or{:system, "ENV_VAR"}
. Similar to:port
, when given a tuple like{:system, "HOST"}
, the host will be referenced fromSystem.get_env("HOST")
at runtime.:static_url
- configuration for generating URLs for static files. It will fallback tourl
if no option is provided. Accepts the same options asurl
.:watchers
- a set of watchers to run alongside your server. It expects a list of tuples containing the executable and its arguments. Watchers are guaranteed to run in the application directory, but only when the server is enabled. For example, the watcher below will run the “watch” mode of the brunch build tool when the server starts. You can configure it to whatever build tool or command you want:[node: ["node_modules/brunch/bin/brunch", "watch"]]
:live_reload
- configuration for the live reload option. Configuration requires a:patterns
option which should be a list of file patterns to watch. When these files change, it will trigger a reload. If you are using a tool like pow in development, you may need to set the:url
option appropriately.live_reload: [ url: "ws://localhost:4000", patterns: [ ~r{priv/static/.*(js|css|png|jpeg|jpg|gif)$}, ~r{web/views/.*(ex)$}, ~r{web/templates/.*(eex)$} ] ]
:pubsub
- configuration for this endpoint’s pubsub adapter. Configuration either requires a:name
of the registered pubsub server or a:name
and:adapter
pair. The pubsub name and adapter are compile time configuration, while the remaining options are runtime. The given adapter and name pair will be started as part of the supervision tree. If no adapter is specified, the pubsub system will work by sending events and subscribing to the given name. Defaults to:[adapter: Phoenix.PubSub.PG2, name: MyApp.PubSub]
It also supports custom adapter configuration:
[name: :my_pubsub, adapter: Phoenix.PubSub.Redis, host: "192.168.100.1"]
Endpoint API
In the previous section, we have used the config/2
function that is
automatically generated in your endpoint. Here’s a list of all the functions
that are automatically defined in your endpoint:
- for handling paths and URLs:
struct_url/0
,url/0
,path/1
,static_url/0
, andstatic_path/1
; - for handling channel subscriptions:
subscribe/2
andunsubscribe/1
; - for broadcasting to channels:
broadcast/3
,broadcast!/3
,broadcast_from/4
, andbroadcast_from!/4
- for configuration:
start_link/0
,config/2
, andconfig_change/2
; - for instrumentation:
instrument/3
; - as required by the
Plug
behaviour:Plug.init/1
andPlug.call/2
.
Instrumentation
Phoenix supports instrumentation through an extensible API. Each endpoint
defines an instrument/3
macro that both users and Phoenix internals can call
to instrument generic events. This macro is responsible for measuring the time
it takes for the event to be processed and for notifying a list of interested
instrumenter modules of this measurement.
You can configure this list of instrumenter modules in the compile-time
configuration of your endpoint. (see the :instrumenters
option above). The
way these modules express their interest in events is by exporting public
functions where the name of each function is the name of an event. For
example, if someone instruments the :render_view
event, then each
instrumenter module interested in that event will have to export
render_view/3
.
Callbacks cycle
The event callback sequence is:
- The event callback is called before the event happens (in this case,
before the view is rendered) with the atom
:start
as the first argument; see the “Before clause” section below. - The event occurs (in this case, the view is rendered).
- The same event callback is called again, this time with the atom
:stop
as the first argument; see the “After clause” section below.
The second and third argument that each event callback takes depends on the
callback being an “after” or a “before” callback i.e. it depends on the
value of the first argument, :start
or :stop
. For this reason, most of
the time you will want to define (at least) two separate clauses for each
event callback, one for the “before” and one for the “after” callbacks.
All event callbacks are run in the same process that calls the instrument/3
macro; hence, instrumenters should be careful to avoid performing blocking actions.
If an event callback fails in any way (exits, throws, or raises), it won’t
affect anything as the error is caught, but the failure will be logged. Note
that “after” callbacks are not guaranteed to be called as, for example, a link
may break before they’ve been called.
“Before” clause
When the first argument to an event callback is :start
, the signature of
that callback is:
event_callback(:start, compile_metadata, runtime_metadata)
where:
compile_metadata
is a map of compile-time metadata about the environment whereinstrument/3
has been called. It contains the module where the instrumentation is happening (under the:module
key), the file and line (:file
and:line
), and the function inside which the instrumentation is happening (under:function
). This information can be used arbitrarily by the callback.runtime_metadata
is a map of runtime data that the instrumentation passes to the callbacks. This can be used for any purposes: for example, when instrumenting the rendering of a view, the name of the view could be passed in these runtime data so that instrumenters know which view is being rendered (instrument(:view_render, %{view: "index.html"}, fn ...)
).
“After” clause
When the first argument to an event callback is :stop
, the signature of that
callback is:
event_callback(:stop, time_diff, result_of_before_callback)
where:
time_diff
is an integer representing the time it took to execute the instrumented function in native units.result_of_before_callback
is the return value of the “before” clause of the sameevent_callback
. This is a means of passing data from the “before” clause to the “after” clause when instrumenting.
The return value of each “before” event callback will be stored and passed to the corresponding “after” callback.
Using instrumentation
Each Phoenix endpoint defines its own instrument/3
macro. This macro is
called like this:
require MyApp.Endpoint
MyApp.Endpoint.instrument(:render_view, %{view: "index.html"}, fn ->
# actual view rendering
end)
All the instrumenter modules that export a render_view/3
function will be
notified of the event so that they can perform their respective actions.
Phoenix default events
By default, Phoenix instruments the following events:
:phoenix_controller_call
- it’s the whole controller pipeline. The%Plug.Conn{}
is passed as runtime metadata.:phoenix_controller_render
- the rendering of a view from a controller. The map of runtime metadata passed to instrumentation callbacks has the:view
key - for the name of the view, e.g.HexWeb.ErrorView
, the:template
key - for the name of the template, e.g.,"index.html"
, the:format
key - for the format of the template, and the:conn
key - containing the%Plug.Conn{}
.:phoenix_channel_join
- the joining of a channel. The%Phoenix.Socket{}
and join params are passed as runtime metadata via:socket
and:params
.:phoenix_channel_receive
- the receipt of an incoming message over a channel. The%Phoenix.Socket{}
, payload, event, and ref are passed as runtime metadata via:socket
,:params
,:event
, and:ref
.
Dynamic instrumentation
If you want to instrument a piece of code, but the endpoint that should
instrument it (the one that contains the instrument/3
macro you want to use)
is not known at compile time, only at runtime, you can use the
Phoenix.Endpoint.instrument/4
macro. Refer to its documentation for more
information.
Link to this section Summary
Functions
Instruments the given function using the instrumentation provided by the given endpoint
Checks if Endpoint’s web server has been configured to start
Defines a mount-point for a Socket module to handle channel definitions
Callbacks
Broadcasts a msg
as event
in the given topic
Broadcasts a msg
as event
in the given topic
Broadcasts a msg
from the given from
as event
in the given topic
Broadcasts a msg
from the given from
as event
in the given topic
Access the endpoint configuration given by key
Reload the endpoint configuration on application upgrades
Initialize the endpoint configuration
Allows instrumenting operation defined by function
Generates the path information when routing to this endpoint
Starts the Endpoint supervision tree
Generates a route to a static file in priv/static
Generates the static URL without any path information
Generates the endpoint base URL, but as a URI
struct
Subscribes the caller to the given topic
Unsubscribes the caller from the given topic
Generates the endpoint base URL without any path information
Link to this section Types
Link to this section Functions
Instruments the given function using the instrumentation provided by the given endpoint.
To specify the endpoint that will provide instrumentation, the first argument can be:
- a module name - the endpoint itself
- a
Plug.Conn
struct - this macro will look for the endpoint module in the:private
field of the connection; if it’s not there,fun
will be executed with no instrumentation - a
Phoenix.Socket
struct - this macro will look for the endpoint module in the:endpoint
field of the socket; if it’s not there,fun
will be executed with no instrumentation
Usually, users should prefer to instrument events using the instrument/3
macro defined in every Phoenix endpoint. This macro should only be used for
cases when the endpoint is dynamic and not known at compile time.
Examples
endpoint = MyApp.Endpoint
Phoenix.Endpoint.instrument endpoint, :render_view, fn -> ... end
Checks if Endpoint’s web server has been configured to start.
otp_app
- The otp app running the endpoint, for example:my_app
endpoint
- The endpoint module, for exampleMyApp.Endpoint
Examples
iex> Phoenix.Endpoint.server?(:my_app, MyApp.Endpoint)
true
Defines a mount-point for a Socket module to handle channel definitions.
Examples
socket "/ws", MyApp.UserSocket
socket "/ws/admin", MyApp.AdminUserSocket
By default, the given path is a websocket upgrade endpoint,
with long-polling fallback. The transports can be configured
within the Socket handler. See Phoenix.Socket
for more information
on defining socket handlers.
Link to this section Callbacks
Broadcasts a msg
as event
in the given topic
.
Broadcasts a msg
as event
in the given topic
.
Raises in case of failures.
Broadcasts a msg
from the given from
as event
in the given topic
.
Broadcasts a msg
from the given from
as event
in the given topic
.
Raises in case of failures.
config(key :: atom(), default :: term()) :: term()
Access the endpoint configuration given by key.
config_change(changed :: term(), removed :: term()) :: term()
Reload the endpoint configuration on application upgrades.
Initialize the endpoint configuration.
Invoked when the endpoint supervisor starts, allows dynamically configuring the endpoint from system environment or other runtime sources.
instrument({line :: Macro.Env.line(), env :: Macro.Env.t()}, instrument_event :: Macro.t(), runtime_metadata :: Macro.t(), funcion :: Macro.t()) :: Macro.t()
Allows instrumenting operation defined by function
.
runtime_metadata
may be omitted and defaults to nil
.
Read more about instrumentation in the “Instrumentation” section.
Generates the path information when routing to this endpoint.
Starts the Endpoint supervision tree.
Starts endpoint’s configuration cache and possibly the servers for handling requests.
Generates a route to a static file in priv/static
Generates the static URL without any path information.
Generates the endpoint base URL, but as a URI
struct.
Subscribes the caller to the given topic.
See Phoenix.PubSub.subscribe/3
for options.
Unsubscribes the caller from the given topic.
Generates the endpoint base URL without any path information.