kelsey_w

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

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

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
18
Post #9
amnu3387

amnu3387

Your phoenix app is working if you visit one of its routes bypassing the plug app?

kelsey_w

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.

chrismccord

chrismccord

Creator of Phoenix

The phoenix router is most definitely a Plug :slight_smile: You can forward to a router as much as you like so that’s not an issue.

mbuhot

mbuhot

Plug.Router — Plug v1.13.6 has an example for using Plug.Router.
It’s different to the Phoenix.Router that would be generated with a new Phoenix app.

I think you could achieve the same effect with a Phoenix.Router using :* as the verb and a glob path:

match(:*, "/some/prefix/*path", SomeOther.Router, nil)

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement