2

背景

我有一个简单的 Plug 路由器,它有一些 POST、PUT 和 GET 端点。但是,每个端点都需要对请求的标头进行特定的验证。我不知道如何使用 Plug 来实现这一点。代码

我有一个非常通用的路由器,它接收请求并将它们重定向到控制器:

defmodule Api do
  use Plug.Router

  alias Api.Controllers.{Product, NotFound, Ping}

  plug :match
  plug Plug.Logger
  plug :dispatch

  get "/ping",  do: Ping.process(conn)
  put "/product",    do: Product.process(conn)

  match _, do: NotFound.process(conn)
end

问题

但是,缺少一个步骤。我需要 /products 端点来验证标头。即标题应该设置一些特定的字段,例如,像“conten-type”标题,甚至是像“bananas”这样的自定义标题。

此验证不适用于所有端点。更糟糕的是,每个端点都会进行自己的验证,例如,具有“bananas”标头对于“/products”端点可能很重要,但“/ping”端点并不真正关心。

研究

我读过这篇文章:

但是,这适用于所有端点并且不是特定的。

问题

  • 是否有可能通过 Plug 实现我正在寻找的东西?如果是这样,怎么做?
4

1 回答 1

1

do您可以在块中为插件中的路径做任何您想做的事情。我有时会为这样的事情使用环绕过滤器模式。就像是:

defmodule Api do
  use Plug.Router

  # ...

  put "/product"  do
    with_valid_headers(conn, fn ->
      Product.process(conn)
    end)
  end

  defp with_valid_headers(conn, action) do
    if get_req_header(conn, "banana") == "Cavendish" do
      action.()
    else
      send_resp(conn, 400, "Invalid banana")
    end
  end

  # ...
end

当然,如果这个验证不会被重用,你可以把它放在do块的主体中​​。

于 2020-10-26T12:26:41.583 回答