jonnifyelixir

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

SUPERVISION TREE PortalWeb.Endpoint added as a supervised child (F5’s tree) supervises ROUTER live "/enroll/:id" → EnrollmentLive (after the pipeline) routes LIVEVIEW mount / handle_event call the Portal facade — nothing else calls

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

PORTAL.SUPERVISOR :one_for_one EVENTSTORE F5 · store ENGINE F5 · GenServer PORTALWEB.ENDPOINT F6 · web (new) the endpoint is one more supervised child; the engine and store entries are unchanged
# 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

Related in this course