kelsey_w
Umbrella App routing with Plug.Router app & Phoenix app
I’ve set up my umbrella app into three apps - simple Plug app, Phoenix app (called Chemistry), and database.
The first app simply receives a request, queries the database for the appropriate record, and redirects to an external url on that record. The second phase of the project was making this app into part of an umbrella app structure and separating the database into its own app. Additionally, I created a Phoenix app to handle uploading images.
Goal: do not load the entire Phoenix app if it’s not necessary. My idea was to set up routing so that the request is forwarded from the Plug app to the Phoenix/Chemistry app.
I’ve not been successful in implementing it this way - only in the opposite direction. When I forward from the Plug app - forward '/chemistry', to: Chemistry.Router - it returns the following compilation error:
(UndefinedFunctionError) function Chemistry.Router.init/1 is undefined (module Chemistry.Router is not available)
Am I not correctly importing the module? Any tips on the best way to handle routes for two applications?
Thanks!
Marked As Solved
amnu3387
I think the problem is that the phoenix router is not a plug, whereas forward is expecting a plug, I think you need to give it the endpoint and not the router?
Also Liked
mbuhot
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
amnu3387
Your phoenix app is working if you visit one of its routes bypassing the plug app?
kelsey_w
Correct. The apps are on different ports (4000 & 4004) so I can access the routes by their corresponding port, but I’d like to go to one port (for the plug app) and be able to access the routes in the Phoenix app.








