如何使用 Plug 功能连接 Plug.Router

How to connect Plug.Router with Plug function

我正在尝试在 Elixir 中设置一个非常简单、基本的 HTTP API。我认为使用 Phoenix 做这样的事情完全是矫枉过正,所以想简单地通过使用 Plug 来完成。我可以通过像这样设置一个基本路由器来做到这一点:

defmodule Example.Router do
  use Plug.Router

  plug Plug.Logger
  plug :match
  plug :dispatch

  get "/" do    
    data = do_something_with_conn(conn)

    send_resp(conn, 200, Poison.encode!(data))
  end

  match _, do: send_resp(conn, 404, "Not Found")
end

但是,我不知道如何将此路由器连接到另一个插件功能。比如说,我在某个地方有这个插件兼容功能:

defmodule RandomPlug do
  import Plug.Conn
  def random_plug(conn, opts) do
    whatever(conn)
  end
end

如何连接到路由器?我尝试使用 docs:

中的语法
forward "/", to: RandomPlug.random_plug

和其他变体,但我无法让它编译 and/or 工作。例如上面的版本抱怨没有 random_plug/0 函数。

是的,我可以让它与整个插件模块(使用 initcall)一起工作,但我想弄清楚如何让它与一个函数一起工作。也许它会让我更好地理解一些 Elixir 的细节,并且根据文档应该是可能的。

我刚刚阅读了 Plug.Builder 的源代码,并没有找到在 plug 中指定模块和函数名称组合的方法。它 seems to be limited to either a function name or a module name(在这种情况下它会调用 module.init/2)。但是,您 可以 import 模块中的函数,然后将导入的函数视为本地函数:

defmodule Example.Router do
  use Plug.Router

  ...

  import RandomPlug
  plug :random_plug
end