Umbrella App routing with Plug.Router app & Phoenix app

We use a very similar setup, here’s how we structured the app:

The plug app defines a router that uses match <path>, to: <plug> to forward requests without altering the path.

  match "/events/*_", to: Events.Router
  match "/exq/*_",    to: Exq.Router
  match "/health",    to: Health.Router
  match "/report/*_", to: Report.Router
  match "/stats/*_",  to: Stats.Router

Then each of the umbrella apps defines a Router module, with Phoenix.Router for the nice url helpers.

We add a TestEndpoint module in each umbrella app under /test/support/test_endpoint.ex and load it conditionally in the Application module based on Mix.env

  def start(_type, _args) do
    children = case Mix.env do
      :test -> [Health.TestEndpoint]
      _ -> []
    end
    Supervisor.start_link(children, strategy: :one_for_one, name: Health.Supervisor)
  end

This allows you to develop each umbrella app in isolation, then stitch them all together with the plug router.

The plug router has to depend on every other app to forward to them:

 defp deps do
    [
      {:events, in_umbrella: true},
      {:health, in_umbrella: true},
      {:stats, in_umbrella: true},
      {:reports, in_umbrella: true},
   ]
  end
17 Likes