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