F6.01 · part 2 of 3
The endpoint, supervised
The endpoint wears two hats, and seeing both is what connects Phoenix to everything F5 built. As a
plug, PortalWeb.Endpoint is the outermost layer of the request
lifecycle — the fixed stack of static files, parsers, and session that every request passes through before
the router. As a process, it is a supervised child of the OTP tree: when the application boots,
the endpoint starts listening, and if it crashes its supervisor restarts it, exactly like the engine and the
store from F5. That second hat is the whole structural change F6 makes — one more child added to the tree
the F5.09 lab assembled, sitting beside the engine rather than wrapping it.
See the endpoint’s two roles, where it sits in the supervision tree, and the code for both — the plug stack and the one-line addition to the tree.
Two roles, one module
The same module is configured two ways. Its plug declarations make it the head of the
request pipeline; its place in Application.start/2 makes it a supervised process that
owns the listening socket. Select a role to see what it covers.
The endpoint’s roles · select one
role: Plug stack
is: static files, parsers, session, router
One module, two contracts: a plug for the request path and a child spec for the supervisor. The first makes it part of the lifecycle; the second makes it part of OTP — the bridge between HTTP and the BEAM.
Where it sits in the tree
The endpoint is added to the supervision tree the F5.09 lab assembled, under the same
:one_for_one strategy. The store and the engine entries do not move; the endpoint is
one more child, started alongside them. A request the endpoint accepts is handled by calling the engine that
is its sibling, never by reaching around the supervisor.
Portal.Supervisor · one new child
A web server that is a supervised process is a BEAM idea, not a Phoenix one. The endpoint inherits the same fault tolerance as the engine: if it falls over, the supervisor brings it back, and the engine beside it never noticed.
The endpoint in code
The endpoint module is mostly an ordered list of plugs ending in the router; both roles are visible in it.
Adding it to the tree is a single line in Application.start/2 — the same list
the F5.09 lab built, with one entry appended.
# the endpoint: the head of the request pipeline (a plug) ... defmodule PortalWeb.Endpoint do use Phoenix.Endpoint, otp_app: :portal socket "/live", Phoenix.LiveView.Socket # LiveView entry (F6.06) plug Plug.Static, at: "/", from: :portal plug Plug.RequestId plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], json_decoder: Jason plug Plug.Session, store: :cookie, key: "_portal_key" plug PortalWeb.Router # the last plug: match → controller end # ... and a supervised child of the F5.09 tree (one line added) children = [ Portal.EventStore.adapter(), # F5 — unchanged {Portal.Engine, []}, # F5 — unchanged PortalWeb.Endpoint # F6 — supervised alongside ] Supervisor.start_link(children, strategy: :one_for_one, name: Portal.Supervisor)
a plug
The outermost layer of the lifecycle — the stack every request passes through.
a process
A supervised child beside the engine — the one structural change F6 makes.
Next: controllers, views & the facade seam — once a request reaches the router, where does your code call the engine?
References
Primary sources for this lesson, and where it connects in the course.
Sources
- Overview — Phoenix documentation — the framework at a glance.
- Request life-cycle — Phoenix documentation — endpoint to view.