stefpankov
Conditional forward in Router based on run-time configuration
I need to use the forward macro in my application’s router only if a configuration flag is true, otherwise I don’t need to forward. I’ve set the config flag to my Endpoint and am trying to access it in the router module as such:
if MyApp.Endpoint.config(:use_sent_emails_plug, false) do
forward "/sent-emails", Bamboo.SentEmailViewerPlug
end
However this approach throws a compilation error:
== Compilation error in file lib/my_app_web/router.ex ==
** (ArgumentError) argument error
(stdlib) :ets.lookup(MyAppWeb.Endpoint, :use_sent_emails_plug)
lib/phoenix/endpoint.ex:540: MyAppWeb.Endpoint.config/2
lib/my_app_web/router.ex:4: (module)
(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
(elixir) lib/kernel/parallel_compiler.ex:229: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7
Thanks in advance for any help and insight.
Marked As Solved
stefpankov
I had the mail adapter be configurable at run-time in the releases.exs config file, however i couldn’t really find a way to use that configuration in the router. After a lot of digging I figured out the whole compile time vs. run-time configuration and realized that there’s really no need for me to configure the mail driver at run-time so now for production I configure the mail driver with an env variable and it can be either local or sendgrid for different target environments.
So now the check looks like this:
if Application.get_env(:my_app, MyApp.Mailer)[:adapter] == Bamboo.LocalAdapter do
forward "/sent-emails", Bamboo.SentEmailViewerPlug
end
Also Liked
arcanemachine
This page is the top Google result for “phoenix conditional router forward”, so I’ll just leave a decently thorough answer that will hopefully help whoever bumps into this thread. (I’ll be honest: It’s probably gonna be me in 6 months!
)
To forward a request to one of several different routers in Phoenix, do this:
- Forward the matching path in your router:
lib/your_project_web/router.ex
scope "/" do
pipe_through :api
forward "/", YourProjectWeb.Plugs.ConditionalRequestForwarder
end
- Create a plug that matches and dispatches to the appropriate router based on your condition:
lib/your_project_web/plugs/conditional_request_forwarder.ex
defmodule YourProjectWeb.Plugs.ConditionalRequestForwarder do
@behaviour Plug
def init(opts), do: opts
def call(%Plug.Conn{} = conn, _opts) do
case conn.params["some_param"] do
nil -> YourProjectWeb.SomeRouter.call(conn, [])
_ -> YourProjectWeb.SomeOtherRouter.call(conn, [])
end
end
end
And that’s how you can conditionally forward a request to one of several possible routers! ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








