Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call plugs from within a plug

I have a few plugs that I call every time. I would like to create a single plug that calls all of them for me. How would I go about doing that?

This is what I've currently tried to do:

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

but it throws a CompileError, saying: undefined function plug

like image 449
Sheharyar Avatar asked Dec 25 '22 01:12

Sheharyar


1 Answers

You can simply use Plug.Builder for this:

defmodule MyApp.SpecialPlug do
  use Plug.Builder

  plug SimplePlug1
  plug SimplePlug2, args: :something
end

This will define init and call automatically which will sequentially pass conn to SimplePlug1 and then SimplePlug2.


If you really want to call a plug manually, you can do something like this:

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

Note that you will have to add the check for halted: true yourself as above (unless you want to ignore halts for some reason). Plug.Builder does the same for you automatically

To get the equivalent of:

plug SimplePlug1
plug SimplePlug2, args: :something

you can now do:

plug MyApp.SpecialPlug, {[], [args: :something]}
like image 99
Dogbert Avatar answered Dec 29 '22 18:12

Dogbert