Нужен ли маршрутизатору Plug конвейер соответствия / отправки? - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть модуль маршрутизатора, который пересылает запрос другим маршрутизаторам.В этом маршрутизаторе у меня есть пиплайн, состоящий из plug(:match) и plug(:dispatch).

defmodule Example.Router do
  use Plug.Router

  plug(:match)
  plug(:dispatch)

  forward("/check", to: Example.Route.Check)

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

Во втором модуле у меня тот же конвейер:

defmodule Example.Route.Check do
  use Plug.Router

  plug(:match)
  plug(:dispatch)

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

Проблема, которую я вижу здесь, заключается в том, что мне всегда нужны plug(:match) и plug(:dispatch)во всех Plug роутерах.Поэтому у меня есть следующие вопросы:

  1. Это действительно необходимо?
  2. Все ли маршрутизаторы должны иметь конвейер в одном файле с маршрутами?

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Хотя ответ @Sheharyar является абсолютно правильным, я бы добавил, что вы можете СУХОЙ, введя свой собственный вспомогательный макрос:

defmodule Example.Route.Common do
  defmacro __using__(opts \\ []) do
    quote do
      use Plug.Router

      plug(:match)
      plug(:dispatch)
    end
  end
end

И используйте его как:

defmodule Example.Route.Check do
  use Example.Route.Common

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

Параметр opts может использоваться для точной настройки включенных штекеров.

Kernel.use/2.

0 голосов
/ 22 ноября 2018

Да, всегда требуются оба штекера:

  • Штекер :match отвечает, ну, в общем, соответствие входящего запроса на один из определенных маршрутов в маршрутизаторе.

  • Подключаемый модуль :dispatch отвечает за окончательную обработку запрос в согласованном маршруте.


Очевидный вопрос здесь будет:

Почему бы просто не сделать это автоматически,так как это нужно делать для каждого запроса?

  1. Для начала, это потому, что имеет философию дизайна вещей явно вместо неявно .

  2. Во-вторых, что более важно, штекеры выполняются в том порядке, в котором они определены .Это дает разработчику полный контроль над тем, как обрабатываются входящие запросы.


Например, вы можете проверить заголовок Authorization перед сопоставлением маршрута и остановить илипродолжить запрос оттуда.Или вы можете захотеть обновить количество просмотров страниц в отдельном процессе, как только будет найден маршрут, но до его обработки.Другой распространенный сценарий - синтаксический анализ запроса JSON после маршрута.

Вы можете сделать все это и многое другое, настроив конвейер:

defmodule Example.Router do
  use Plug.Router

  plug(CheckRateLimit)
  plug(VerifyAuthHeader)
  plug(:match)
  plug(LogWebRequest)
  plug(Plug.Parsers, parsers: [:json], ...)
  plug(:dispatch)

  # ...
end

Возможность пересылки согласованных маршрутов на другие маршрутизаторы может сделать ваш веб-сервер намного более сложным.Например, вы можете проверить ограничение скорости API в базовом маршрутизаторе, перенаправить маршруты /admin на отдельный AuthorizedRouter и вставить туда специальный плагин VerifyAuthHeader до того, как эти маршруты будут сопоставлены.

...