F6 · system design · 3 of 3
Wiring Phoenix onto the F5 engine
This is the seam the whole chapter turns on, and it is smaller than it sounds. There are three
wiring points. First, the supervision tree: Phoenix’s Endpoint
becomes one more child of the tree the F5.09 lab assembled, supervised alongside the engine and the store.
Second, the router: a live route maps a URL to a LiveView after the plug pipeline runs. Third,
the LiveView itself, which — exactly like the F5.09 sketch — calls only the
Portal facade. No part of this reaches into the engine; F6 adds a child, a route, and a
caller, and the engine stays the framework-free core F5 built.
Select a wiring point to see what connects to what. All three are additions on top of the F5 engine, never edits inside it.
Three wiring points
Each point is a one-way connection from Phoenix to the engine. The tree supervises the endpoint; the router sends a request to a LiveView; the LiveView calls the facade. Nothing points the other way. Select a point.
Wiring points · select one
point: Supervision tree
connects: PortalWeb.Endpoint joins F5’s tree
Three additions, one direction. Phoenix depends on the engine; the engine depends on nothing above it. That asymmetry is the entire reason the wiring is small.
The endpoint joins the tree
The first wiring point is the supervision tree from the F5.09 lab. F6 adds exactly one child —
PortalWeb.Endpoint — under the same :one_for_one
strategy. The engine and the store entries do not change, so the web layer is supervised next to them rather
than wrapped around them.
One tree, one new child
# F6 adds one child to the tree the F5.09 lab assembled defmodule Portal.Application do use Application @impl true def start(_type, _args) do 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) end end
The route and the LiveView
The second and third points are a route and a caller. The router maps a URL to a LiveView, running the plug
pipeline first; the LiveView loads its state from a facade query in mount. This is the
same EnrollmentLive the F5.09 lab sketched — now reached by a real route, still
calling only Portal.
# the router: a live route maps a URL to a LiveView, after the pipeline defmodule PortalWeb.Router do use PortalWeb, :router scope "/", PortalWeb do pipe_through :browser live "/enroll/:id", EnrollmentLive end end
And the LiveView the route reaches — its mount loads state through the facade,
nothing more:
# the LiveView from the F5.09 sketch, now real — still only the facade def mount(%{"id" => id}, _session, socket) do case Portal.progress_of(id) do {:ok, percent} -> {:ok, assign(socket, progress: percent, error: nil)} {:error, %Portal.Error{message: msg}} -> {:ok, assign(socket, error: msg)} end end
add, do not edit
A child, a route, a caller — three additions on top of the F5 engine.
one direction only
Phoenix depends on the facade; the engine depends on nothing above it.
That closes the F6 design brief. The chapter proper starts at F6.01 — Architecture & the request lifecycle, building the platform one layer at a time. Back to the F6 overview.
References
The three things F6 wires onto the engine: the endpoint, the router, and the LiveView.
Sources
- Phoenix — Endpoint — the supervised child that joins the tree.
- Phoenix — Router — mapping a live route to a LiveView.
- Elixir — Supervisor — the F5 tree the endpoint is added to.
Related in this course
- F6.0.1 · The developer journey — where this seam sits on the path.
- F6.0.2 · What we’re building — the stack this connects.
- F5.09.3 · What ships in F6 — the handoff this implements.
- F5.09.2 · A LiveView mount sketch — the LiveView, sketched.