Elixir 插件中的版本控制 API
Versioning API in Elixir Plug
我有两个模块: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 children
,我的端点可以正常工作
Plug.Cowboy.child_spec(scheme: :http, plug: Http.Endpoints.V1.Base, options: [port: Application.get_env(:http, :port)])
但我希望我的应用程序启动所有端点版本。
我尝试用 require Http.Endpoints.V1.Base
和 require Http.Endpoints.V2.Base
创建 lib/endpoints.ex 并更改了我的 applications.ex 但它没有用。
您可以从端点文件转发到其他路由器。这是 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
。
干杯!
My endpoint works correctly if I put in my applications.ex the
children
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()
似乎更容易,而不是试图计算参数周围需要多少个括号。
我有两个模块: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 children
,我的端点可以正常工作Plug.Cowboy.child_spec(scheme: :http, plug: Http.Endpoints.V1.Base, options: [port: Application.get_env(:http, :port)])
但我希望我的应用程序启动所有端点版本。
我尝试用 require Http.Endpoints.V1.Base
和 require Http.Endpoints.V2.Base
创建 lib/endpoints.ex 并更改了我的 applications.ex 但它没有用。
您可以从端点文件转发到其他路由器。这是 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
。
干杯!
My endpoint works correctly if I put in my applications.ex the children
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()
似乎更容易,而不是试图计算参数周围需要多少个括号。