繁体   English   中英

如何在Elixir中插入管道?

[英]How to do Plug pipelines in Elixir?

背景

我有一个应用程序,它是带有牛仔的网络服务器,并使用插件。 由于此应用程序是继承的,因此除非我们重新制作整件事,否则使用Phoenix是不可能的。

我的目标是要不要将所有内容都放在一个大文件中,而是要有几个插头并通过管道将它们连接起来。

假设我有一个主路由器插件,如下所示:

defmodule MyApp.Web.Router do
  use Plug.Router

  plug(:match)

  forward "/check", to: MyApp.Route.Check
  forward "/dispatch", to: MyApp.Plug.Dispatch      
end

所以在这里我有两件事。 端点/check路由,如下所示:

defmodule MyApp.Route.Check do
  use Plug.Router

  plug(:dispatch)

  get "/", do: send_resp(conn, 200, "ok")
end

/dispatch的Plug管道如下所示:

defmodule MyApp.Plug.Dispatch do
  use Plug.Builder

  plug(Plug.Parsers, parsers: [:urlencoded])   #parses parameters
  plug(MyApp.Plug.Metrics)                     #exposes /metrics path
  plug(Cipher.ValidatePlug)                    #typical URL validation
  plug(MyApp.Route.Dispatch)                   #forwards to dispatch Route 
end

该管道解析参数,通知度量服务,验证请求,然后将其发送到适当的路由器,如下所示:

defmodule MyApp.Route.Dispatch do
  use Plug.Router

  plug(:dispatch)

  get "/", do: send_resp(conn, 200, "Info dispatched")
end

问题

这里的问题是没有任何效果。 从字面上看,如果我启动该应用程序并尝试访问即使是最笨的终结点( /check ),代码也会因错误而失败:

17:44:03.330 [error] #PID<0.402.0> running MyApp.Web.Router (connection #PID<0.401.0>, stream id 1) terminated
Server: localhost:4003 (http)
Request: GET /check
** (exit) an exception was raised:
    ** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection
        (plug_cowboy) lib/plug/cowboy/handler.ex:37: Plug.Cowboy.Handler.maybe_send/2
        (plug_cowboy) lib/plug/cowboy/handler.ex:13: Plug.Cowboy.Handler.init/2
        (...)

现在,我整天都在阅读文档,而这是我所得到的。 该应用程序非常简单,几乎是插件的世界:

https://elixirschool.com/en/lessons/specifics/plug/

但是使用MyApp.Web.Router而不是它们使用的那个。

可以在此处看到MWE:

https://github.com/Fl4m3Ph03n1x/plug-pipeline-problem

我究竟做错了什么?

路由在Example.Route.DispatchExample.Route.Check上不匹配。 要解决此问题,您需要进行两项更改:

defmodule Example.Route.Dispatch do
  use Plug.Router

  plug(:dispatch)

  get "/*glob", do: send_resp(conn, 200, "Info dispatched")
end

defmodule Example.Route.Check do
  use Plug.Router

  plug :match
  plug :dispatch

  get "/*glob" do
    send_resp(conn, 200, "ok")
  end
end

或者,您可以执行以下操作: https : //github.com/Fl4m3Ph03n1x/plug-pipeline-problem/pull/1

要了解有关其为什么不匹配的更多信息,可以对“全部捕获”匹配使用Plug.Router.match_path / 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM