Siscia
Siscia

Reputation: 1491

Plug, use option passed at init with Plug.Router syntax

I am using Plug and I would like to understand.

My code looks like:

defmodule Numerino.Plug do
  use Plug.Router
  use Plug.Debugger

  plug :put_resp_content_type, "application/json"
  plug :match
  plug :dispatch

  def init options do
    IO.inspect options
    options
  end

  get "/" do
    conn
    |> IO.inspect
    |> send_resp(201, "world")
  end

  match _ do
    send_resp(conn, 404, "Not found.")
  end

end

Inside the get I would need to use the option passed as argument.

How can I access the options keeping the same Plug.Router syntax ?

Upvotes: 5

Views: 1128

Answers (2)

Meta Lambda
Meta Lambda

Reputation: 723

You just have to override the call callback:

  def call(conn, opts) do
    put_private(conn, :opts, opts)
    |> super(opts)
  end

Upvotes: 1

Gazler
Gazler

Reputation: 84150

You haven't specified why you want to do this, so I can only give a generic answer. If you have a specific use case then there may be a better solution.


You can do this by adding an additional plug to the router which stores the opts in the private storage of the conn:

plug :opts_to_private

defp opts_to_private(conn, opts) do
  put_private(conn, :my_app_opts, opts)
end

This will then be accessible in your routes with conn.private.my_app_opts:

get "/" do
  conn.private.my_app_opts
  |> IO.inspect

  conn
  |> send_resp(201, "world")
end

The dispatch function is defoverridable/1 so you can also do the same thing by overriding the function:

defp dispatch(conn, opts) do
  conn = put_private(conn, :my_app_opts, opts)
  super(conn, opts)
end

However I find defining a new function such as opts_to_private cleaner.

Upvotes: 4

Related Questions