I have a Plug.Router
application that receives some options. I need to pass these options to other plugs via forward
but I don't know how to do it.
This is the main router. It receives requests and decides where to forward them.
defmodule MyApp.Web.Router do
use Plug.Router
plug(:match)
plug(:dispatch)
#Here I check that I get options!
def init(father_opts), do: IO.puts("#{__MODULE__} => #{inspect father_opts}")
forward "/api/v1", to: MyApp.Web.Route.API.V1, init_opts: father_opts??
end
As you can probably guess, this won't work. I want my forward
call to access the father_opts
this router is receiving, but I can't access them.
At first I though about the following code snippet:
def init(opts), do: opts
def call(conn, father_opts) do
forward "/api/v1", to: MyApp.Web.Route.API.V1, init_opts: father_opts
end
But this doesn't work because I can't put a forward
inside a call
.
So how do I achieve my objective using forward
?
There is an option adding a top-level plug that will store the father options on private
and you can fetch that on children call
.
Something like:
defmodule Example.Router do
def init(opts), do: opts
def call(conn, options) do
Example.RouterMatch.call(Plug.Conn.put_private(conn, :father_options, options), Example.RouterMatch.init(options))
end
end
defmodule Example.RouterMatch do
use Plug.Router
plug :match
plug :dispatch
forward "/check", to: Example.Route.Check
forward "/dispatch", to: Example.Plug.Dispatch
end
Then you can fetch options on the conn in Example.Route.Check.call/2
.