Phoenix v1.2.0 Phoenix.Endpoint

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 where requests are sent 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 phoenix.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

Before being used, an endpoint must be explicitly started as part of your application supervision tree too (which is again done by default in generated applications):

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 and written through the config/2 function:

YourApp.Endpoint.config(:port)
YourApp.Endpoint.config(:some_config, :default_value)

Compile-time configuration

  • :code_reloader - when true, enables code reloading functionality

  • :debug_errors - when true, uses Plug.Debugger functionality for debugging failures in the application. Recommended to be set to true only in development as it allows listing of the application source code during debugging. Defaults to false.

  • :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

  • :root - the root of your application for running external commands. This is only required if the watchers or code reloading functionality are enabled.

  • :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/manifest.json” which is the file automatically generated by mix phoenix.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 by Plug.Adapters.Cowboy. Defaults to false.

  • :https - the configuration for the HTTPS server. Currently uses cowboy and accepts all options as defined by Plug.Adapters.Cowboy. Defaults to false.

  • :force_ssl - ensures no data is ever sent via http, always redirecting to https. It expects a list of options which are forwarded to Plug.SSL. By default, it redirects http requests and sets the “strict-transport-security” header for https ones.

  • :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 to nil as it must be set per application.

  • :server - when true, starts the web server when the endpoint supervision tree starts. Defaults to false. The mix phoenix.server task automatically sets this to true.

  • :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 from System.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 tourlif 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:patternsoption 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](http://pow.cx) in development, you may need to set the:urloption 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:nameof the registered pubsub server or a:nameand:adapterpair. 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 theconfig/2function which is automatically generated in your endpoint. Here is a summary of all the functions that are automatically defined in your endpoint. #### Paths and URLs *struct_url()- generates the endpoint base URL but as aURIstruct *url()- generates the endpoint base URL without any path information *path(path)- generates the path information when routing to this endpoint *static_url()- generates the static URL without any path information *static_path(path)- generates a route to a static file inpriv/static#### Channels *subscribe(topic, opts)- subscribes the caller to the given topic. SeePhoenix.PubSub.subscribe/3for options. *unsubscribe(topic)- unsubscribes the caller from the given topic. *broadcast(topic, event, msg)- broadcasts amsgwith aseventin the giventopic. *broadcast!(topic, event, msg)- broadcasts amsgwith aseventin the giventopic. Raises in case of failures. *broadcast_from(from, topic, event, msg)- broadcasts amsgfrom the givenfromaseventin the giventopic. *broadcast_from!(from, topic, event, msg)- broadcasts amsgfrom the givenfromaseventin the giventopic. Raises in case of failures. #### Endpoint configuration *start_link()- starts the Endpoint supervision tree, including its configuration cache and possibly the servers for handling requests *config(key, default)- access the endpoint configuration given by key *config_change(changed, removed)- reload the endpoint configuration on application upgrades #### Plug API *init(opts)- invoked when starting the endpoint server *call(conn, opts)- invoked on every request (simply dispatches to the defined plug pipeline) #### Instrumentation API *instrument(event, runtime_metadata \ nil, function)- read more about instrumentation in the "Instrumentation" section ## Instrumentation Phoenix supports instrumentation through an extensible API. Each endpoint defines aninstrument/3macro 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 happen 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:instrumentersoption 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_viewevent, then each instrumenter module interested in that event will have to exportrender_view/3. **Note**: since the configuration for the list of instrumenters is specified at compile time but it's used inside Phoenix itself, if you change this configuration you'll have to recompile Phoenix manually: $ mix deps.compile phoenix $ mix compile ### Callbacks cycle The way event callbacks are called is the following. 1. The event callback is called *before* the event happens (in this case, before the view is rendered) with the atom:startas the first argument; see the "Before clause" section below. 2. The event happens (in this case, the view is rendered). 3. The same event callback is called again, this time with the atom:stopas the first argument; see the "After clause" section below. The second and third argument that each event callback takes depend on the callback being an "after" or a "before" callback (i.e., they depend on the value of the first argument,:startor: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 theinstrument/3macro; hence, instrumenters should be careful in performing blocking actions. If an event callback fails in any way (exits, throws, or raises), it won't affect anything (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_metadatais a map of compile-time metadata about the environment whereinstrument/3has been called. It contains the module where the instrumentation is happening (under the:modulekey), the file and line (:fileand:line), and the function inside which the instrumentation is happening (under:function). This information can be used arbitrarely by the callback. *runtime_metadatais 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_diffis an integer representing the time it took to execute the instrumented function **in native units**. *result_of_before_callbackis 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 owninstrument/3macro. 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 arender_view/3function 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:templatekey - for the name of the template, e.g.,”index.html”- and the:formatkey - for the format of the template. *:phoenix_channel_join- the joining of a channel. The%Phoenix.Socket{}and join params are passed as runtime metadata via:socketand:params. *:phoenix_channel_receive- the receiving 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 theinstrument/3macro you want to use) is not known at compile time, but only at runtime, then you can use the [Phoenix.Endpoint.instrument/4`](Phoenix.Endpoint.html#instrument/4) macro. Refer to its documentation for more information.

Summary

Functions

Checks if Endpoint’s web server has been configured to start

Macros

Instruments the given function using the instrumentation provided by the given endpoint

Stores a plug to be executed as part of the pipeline

Defines a mount-point for a Socket module to handle channel definitions

Functions

server?(otp_app, endpoint)

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 example MyApp.Endpoint

Exampes

iex> Phoenix.Endpoint.server?(:my_app, MyApp.Endpoint)
true

Macros

instrument(endpoint_or_conn_or_socket, event, runtime \\ Macro.escape(%{}), fun)

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 instead.

Examples

endpoint = MyApp.Endpoint
Phoenix.Endpoint.instrument endpoint, :render_view, fn -> ... end
plug(plug, opts \\ [])

Stores a plug to be executed as part of the pipeline.

socket(path, module)

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.