Hello everyone, is it possible to dispatch a request to a specific module using plug.router? Phoenix does it using its own macros but I’d like to know how to achieve the same or at least close results using only plug.router
Hi @newton-peixoto yes there are examples of this on the first page of the plug docs, give it a whirl and we’ll be here if you run into issues!
Hello, thanks for replying. I read the doc but I’m probably missing something. The closest thing that I found was the foward macro but it fowards to another plug not to a module with implementation maybe the :do option should do it?
EDIT#
I was thinking something like this
get "/baz", do: &HelloWorld.Controller.show/1
but it did not work
The convention is to do this:
get "/baz", HelloWorld.Controller, :show
the :show
atom represents the name of the controller action that will handle the incoming request.
A controller action is a specific type of function that is designed to handle a specific type of request.
Phoenix is basically a giant function on a web connection (and then socket) that is broken down into a tiny steps so controller action functions would always need an arity of at least 2: one parameter for the connection and one for any parameters that might be needed for the change to the connection.
Off the top of my head, it might be worth trying to pass in conn
without using the capture operator. Also, check out these other requirements from the Plug.Router
docs:
Each route receives a
conn
variable containing aPlug.Conn
struct and it needs to return a connection, as per the Plug spec…
EachPlug.Router
has a plug pipeline, defined byPlug.Builder
, and by default it requires two plugs::match
and:dispatch
. ``
So maybe something like this for a minimal example using only Plug.Router
:
defmodule AppRouter do
use Plug.Router
plug :match # required by default
plug :dispatch # required by default
get "/baz" do
HelloWorld.Controller.show(conn) # must accept and return a connection
end
end
Another option is using forward
. Phoenix controllers are also module plugs with MyApp.Controller.call(conn, :action)
So e.g.
defmodule AppRouter do
use Plug.Router
plug :match # required by default
plug :dispatch # required by default
forward "/baz", to: HelloWorld.Controller, init_opts: :show
end
Keep in mind that Plug.Router.forward
has different options than Phoenix.Router.forward
, so don’t confuse them.