3

我有两个模块:lib/endpoints/v1/base.ex 和 lib/endpoints/v2/base.ex。

lib/endpoints/v1/base.ex

defmodule Http.Endpoints.V1.Base do
  require Logger
  use Plug.Router

  plug(:match)
  plug(:dispatch)
  plug(Plug.Logger)
  plug(Plug.Parsers, parsers: [:json], json_decoder: Poison)

  get "/v1/ping" do
    send_resp(conn, 200, "pong!")
  end
end

lib/endpoints/v2/base.ex

defmodule Http.Endpoints.V2.Base do
  require Logger
  use Plug.Router

  plug(:match)
  plug(:dispatch)
  plug(Plug.Logger)
  plug(Plug.Parsers, parsers: [:json], json_decoder: Poison)

  get "/v2/ping" do
    send_resp(conn, 200, "pong! 2")
  end
end

如果我把我的 applications.ex 孩子放进去,我的端点可以正常工作

Plug.Cowboy.child_spec(scheme: :http, plug: Http.Endpoints.V1.Base, options: [port: Application.get_env(:http, :port)])

但我希望我的应用程序启动所有端点版本。

我尝试使用 and 创建 lib/endpoints.exrequire Http.Endpoints.V1.Baserequire Http.Endpoints.V2.Base更改了我的 applications.ex 但它不起作用。

4

2 回答 2

6

您可以从端点文件转发到其他路由器。这是该forward/2功能的文档:https ://hexdocs.pm/plug/Plug.Router.html#forward/2

基本上,您为 v1 和 v2 创建了 2 个路由器:

defmodule MyAppWeb.V2.Router do
  use Plug.Router

  plug :match
  plug :dispatch

  get "/ping" do
    send_resp(conn, 200, "OK")
  end
end

defmodule MyAppWeb.V1.Router do
  use Plug.Router

  plug :match
  plug :dispatch

  get "/ping" do
    send_resp(conn, 200, "OK")
  end
end

然后在您的端点中,您可以添加所有常见功能并转发到您的版本化路由,如下所示:

defmodule MyAppWeb.Endpoint do
  require Logger
  use Plug.Router

  plug :match
  plug :dispatch
  plug Plug.Logger
  plug Plug.Parsers, parsers: [:json], json_decoder: Poison

  # Forwarding
  forward "/v2", to: MyApp.V2.Router
  forward "/v1", to: MyApp.V1.Router

  # You should put a catch-all here
  match _ do
    send_resp(conn, 404, "Not Found")
  end
end

然后在您的application.ex文件中,像以前一样挂载您的端点。但是,此时您应该能够从同一个端口ping/v1/ping两者。/v2/ping

干杯!

于 2019-07-11T19:35:51.343 回答
1

如果我把我的 applications.ex 孩子放进去,我的端点可以正常工作

Plug.Cowboy.child_spec(
   scheme: :http, 
   plug: Http.Endpoints.V1.Base, 
   options: [port: Application.get_env(:http, :port)]
)

指定它的现代方法是:

{Plug.Cowboy, [[ 
      scheme: :http, 
      plug: Http.Endpoints.V1.Base, 
      options: [port: Application.get_env(:http, :port)]
    ]]
}

见:https ://hexdocs.pm/elixir/Supervisor.html#module-child_spec-1

虽然,对我来说,直接调用似乎更容易child_spec(),而不是试图计算出参数周围需要多少个括号。

于 2019-07-12T00:50:22.390 回答