编译enElixir程序时执行的函数
我有这种让我发疯的奇怪行为!我有以下插件,用于检查 API 客户端是否在x-api-key标头中实际提供了正确的 API 密钥:
defmodule APIServer.APIKeyAuthPlug do
# import Plug.Conn
require Logger
alias APIServer.Util
def init(opts) do
{:ok, options} = opts[:auth]
apikey = options[:apikey]
Logger.debug("API key is #{inspect(apikey)}")
apikey
end
def call(conn, key) do
conn_key = Plug.Conn.get_req_header(conn, "x-api-key") |> hd
Logger.debug("Registered key #{inspect(key)}")
# rest of the call function
end
end
插件插入路由器中的插件链中:
plug Plug.Logger, log: :info
plug APIKeyAuthPlug,
auth: Application.fetch_env(:probe_server, APIServer.APIKeyAuthPlug)
plug(:match)
plug(:dispatch)
正确的密钥本身被定义为环境变量并被读入config.exs:
config :api_server, APIServer.APIKeyAuthPlug,
apikey: System.get_env("API_SERVER_APIKEY") || "XYZ"
现在,当我编译代码,行Logger.debug("API key is #{inspect(apikey)}")的init函数(只有函数)被实际执行:
maurycy@kali> mix compile
Compiling 2 files (.ex)
16:17:59.774 [debug] API key is "XYZ"
任何的想法 ?
回答
路由器中对Plug.Builder.plug/2( plug APIKeyAuthPlug, ...) 的调用导致init/1在编译期间调用 ,除非mode显式设置为:runtime而不是默认值:compile https://github.com/elixir-plug/plug/blob/v1.11.1/lib/plug/builder,。前#L275
设置init_mode: :runtime将解决问题。