Elixir 从插头内部调用插头

Elixir 从插头内部调用插头,elixir,phoenix-framework,Elixir,Phoenix Framework,我有几个插头,我每次都打。我想创建一个插件,为我调用所有这些插件。我该怎么做呢 这就是我目前尝试做的: defmodule MyApp.SpecialPlug do import Plug.Conn def init(default), do: default def call(conn, default) do plug SimplePlug1 plug SimplePlug2, args: :something end end 但是它抛出了一个编译器错误

我有几个插头,我每次都打。我想创建一个插件,为我调用所有这些插件。我该怎么做呢

这就是我目前尝试做的:

defmodule MyApp.SpecialPlug do
  import Plug.Conn

  def init(default), do: default

  def call(conn, default) do
    plug SimplePlug1
    plug SimplePlug2, args: :something
  end
end
但是它抛出了一个
编译器错误
,说:
未定义的函数插件

,您可以简单地使用它:

defmodule MyApp.SpecialPlug do
  use Plug.Builder

  plug SimplePlug1
  plug SimplePlug2, args: :something
end
这将自动定义
init
call
,然后依次将
conn
传递到
SimplePlug1
,然后再传递到
SimplePlug2


如果确实要手动调用插头,可以执行以下操作:

defmodule MyApp.SpecialPlug do
  def init({opts1, opts2}) do
    {SimplePlug1.init(opts1), SimplePlug2.init(opts2)}
  end

  def call(conn, {opts1, opts2}) do
    case SimplePlug1.call(conn, opts1) do
      %Plug.Conn{halted: true} = conn -> conn
      conn -> SimplePlug2.call(conn, opts2)
    end
  end
end
请注意,您必须像上面那样添加对
stapped:true
的检查(除非您出于某种原因想要忽略停止)
Plug.Builder会自动为您执行相同的操作

要获得等效值,请执行以下操作:

plug SimplePlug1
plug SimplePlug2, args: :something
您现在可以执行以下操作:

plug MyApp.SpecialPlug, {[], [args: :something]}

令人惊叹的!谢谢这解决了我的问题,但另一个问题是:如何使用Plug.Builder用我的(非Plug)代码编写其他插件?i、 e.我可以在plug的
call/2
方法中使用
plug/1
方法吗?您可以通过
plug:hello
SimplePlug1
SimplePlug2
之间插入自己的实现,然后定义
hello/2
。或者您想在
call/2
函数中添加基于代码的插件吗?您的
hello
示例似乎是一个很好的方法,但仍然很好奇我如何在
call/2
中调用插件,使用它做些什么,然后在新的
conn
上调用另一个插件。