Spec-Zone.ru › Phoenix

Phoenix.Router

Исходный код

Определяет маршрутизатор Phoenix.

Маршрутизатор предоставляет набор макросов для создания маршрутов, перенаправляющих запросы к определённым контроллерам и действиям. Эти макросы названы в соответствии с HTTP-методами. Например:

defmodule MyAppWeb.Router do
  use Phoenix.Router

  get "/pages/:page", PageController, :show
end

Макрос get/3, приведённый выше, принимает запрос к /pages/hello и перенаправляет его к действию show контроллера PageController с %{"page" => "hello"} в params.

Маршрутизатор Phoenix чрезвычайно эффективен, поскольку использует сопоставление с образцом в Elixir для сопоставления маршрутов и обработки запросов.

Маршрутизация

Для создания маршрутов используются макросы get/3, post/3, put/3 и другие макросы, названные в соответствии с HTTP-методами.

Маршрут:

get "/pages", PageController, :index

сопоставляется с запросом GET к /pages и перенаправляет его к действию index в PageController.

get "/pages/:page", PageController, :show

сопоставляется с /pages/hello и перенаправляет запрос к действию show с %{"page" => "hello"} в params.

defmodule PageController do
  def show(conn, params) do
    # %{"page" => "hello"} == params
  end
end

Можно сопоставлять частичные и множественные сегменты. Например:

get "/api/v:version/pages/:id", PageController, :show

сопоставляется с /api/v1/pages/2 и помещает %{"version" => "1", "id" => "2"} в params. Захватить можно только конечную часть сегмента.

Маршруты сопоставляются сверху вниз. Второй маршрут здесь:

get "/pages/:page", PageController, :show
get "/pages/hello", PageController, :hello

никогда не сопоставится с /pages/hello, поскольку первым с ним сопоставляется /pages/:page.

В маршрутах можно использовать шаблоны, похожие на glob, для сопоставления конечных сегментов.

get "/pages/*page", PageController, :show

сопоставляется с /pages/hello/world и помещает сегменты, сопоставленные с помощью glob-шаблона, в params["page"].

GET /pages/hello/world
%{"page" => ["hello", "world"]} = params

У glob-шаблонов не может быть префиксов и суффиксов, но их можно сочетать с переменными:

get "/pages/he:page/*rest", PageController, :show

сопоставляется с

GET /pages/hello
%{"page" => "llo", "rest" => []} = params

GET /pages/hey/there/world
%{"page" => "y", "rest" => ["there" "world"]} = params

Зачем нужны макросы?

Phoenix старается свести использование макросов к минимуму. Однако вы могли заметить, что Phoenix.Router активно использует макросы. Почему?

Для определения маршрутов используются get, post, put и delete. Макросы применяются для двух целей:

  • Они определяют механизм маршрутизации, который используется при каждом запросе для выбора контроллера, которому нужно его передать. Благодаря макросам Phoenix компилирует все ваши маршруты в один оператор case с правилами сопоставления с образцом, который VM Erlang значительно оптимизирует

  • Для каждого определённого вами маршрута мы также создаём метаданные, необходимые для реализации Phoenix.VerifiedRoutes. Как мы скоро узнаем, проверенные маршруты позволяют ссылаться на любой маршрут как на обычную строку, при этом компилятор проверяет её корректность (что значительно снижает вероятность отправки в рабочую среду неработающих ссылок, форм, писем и т. д.)

Иными словами, маршрутизатор использует макросы для создания более быстрых и безопасных приложений. Также помните, что макросы в Elixir работают только на этапе компиляции, что обеспечивает высокую стабильность после компиляции кода. Phoenix также позволяет получать информацию обо всех определённых маршрутах с помощью задачи mix phx.routes.

Создание маршрутов

Чтобы создавать маршруты в приложении, ознакомьтесь с документацией Phoenix.VerifiedRoutes по созданию маршрутов на основе ~p — предпочтительному способу создания путей и URL-адресов маршрутов с проверкой во время компиляции.

Phoenix также поддерживает создание функциональных помощников — механизм, использовавшийся по умолчанию в Phoenix v1.6 и более ранних версиях. Рассмотрим его далее.

Помощники (устарели)

По умолчанию Phoenix создаёт внутри маршрутизатора модуль Helpers, содержащий именованные помощники, которые помогают разработчикам создавать маршруты и поддерживать их актуальность. Чтобы отключить помощники, передайте helpers: false в use Phoenix.Router.

Помощники создаются автоматически на основе имени контроллера. Например, маршрут:

get "/pages/:page", PageController, :show

создаст следующий именованный помощник:

MyAppWeb.Router.Helpers.page_path(conn_or_endpoint, :show, "hello")
"/pages/hello"

MyAppWeb.Router.Helpers.page_path(conn_or_endpoint, :show, "hello", some: "query")
"/pages/hello?some=query"

MyAppWeb.Router.Helpers.page_url(conn_or_endpoint, :show, "hello")
"http://example.com/pages/hello"

MyAppWeb.Router.Helpers.page_url(conn_or_endpoint, :show, "hello", some: "query")
"http://example.com/pages/hello?some=query"

Если маршрут содержит шаблоны, похожие на glob, соответствующие параметры необходимо передать в виде списка:

MyAppWeb.Router.Helpers.page_path(conn_or_endpoint, :show, ["hello", "world"])
"/pages/hello/world"

URL-адрес, создаваемый именованными помощниками URL, зависит от конфигурации :url, :http и :https. Однако, если по какой-либо причине вам нужно управлять созданием URL вручную, помощникам URL также можно передать структуру URI:

uri = %URI{scheme: "https", host: "other.example.com"}
MyAppWeb.Router.Helpers.page_url(uri, :show, "hello")
"https://other.example.com/pages/hello"

Именованный помощник также можно настроить с помощью параметра :as. Для маршрута:

get "/pages/:page", PageController, :show, as: :special_page

именованный помощник будет таким:

MyAppWeb.Router.Helpers.special_page_path(conn, :show, "hello")
"/pages/hello"

Области и ресурсы

В приложениях Phoenix часто все маршруты помещают в пространство имён области приложения:

scope "/", MyAppWeb do
  get "/pages/:id", PageController, :show
end

Приведённый выше маршрут перенаправит запрос к MyAppWeb.PageController. Такой синтаксис удобен для разработчиков, поскольку позволяет не повторять префикс MyAppWeb. во всех маршрутах.

Как и для всех путей, можно определить динамические сегменты, которые будут переданы в контроллер в качестве параметров:

scope "/api/:version", MyAppWeb do
  get "/pages/:id", PageController, :show
end

Например, приведённый выше маршрут сопоставится с путём "/api/v1/pages/1", а аргумент params в контроллере будет содержать карту с ключом :version и значением "v1".

Phoenix также предоставляет макрос resources/4, позволяющий разработчикам создавать «RESTful»-маршруты для заданного ресурса:

defmodule MyAppWeb.Router do
  use Phoenix.Router, helpers: false

  resources "/pages", PageController, only: [:show]
  resources "/users", UserController, except: [:delete]
end

Наконец, Phoenix включает задачу mix phx.routes, которая наглядно форматирует все маршруты заданного маршрутизатора. С её помощью можно проверить все маршруты, включённые в приведённый выше маршрутизатор:

$ mix phx.routes
GET    /pages/:id       PageController.show/2
GET    /users           UserController.index/2
GET    /users/:id/edit  UserController.edit/2
GET    /users/new       UserController.new/2
GET    /users/:id       UserController.show/2
POST   /users           UserController.create/2
PATCH  /users/:id       UserController.update/2
PUT    /users/:id       UserController.update/2

Маршрутизатор также можно явно передать задаче в качестве аргумента:

$ mix phx.routes MyAppWeb.Router

Дополнительную информацию см. в разделах scope/2 и resources/4.

Конвейеры и плагины

Когда запрос поступает в маршрутизатор Phoenix, он проходит через ряд преобразований в конвейерах, пока не будет перенаправлен к нужному маршруту.

Эти преобразования задаются с помощью плагинов, как определено в спецификации Plug. После определения конвейера его можно подключить к каждой области.

Например:

defmodule MyAppWeb.Router do
  use Phoenix.Router

  pipeline :browser do
    plug :fetch_session
    plug :accepts, ["html"]
  end

  scope "/" do
    pipe_through :browser

    # browser related routes and resources
  end
end

Phoenix.Router импортирует функции из Plug.Conn и Phoenix.Controller, помогающие определять плагины. В приведённом выше примере fetch_session/2 импортирован из Plug.Conn, а accepts/2 — из Phoenix.Controller.

Обратите внимание: конвейеры маршрутизатора запускаются только после обнаружения маршрута. Если совпадений не найдено, плагины не запускаются.

Дополнительная информация

Дополнительную информацию и примеры использования в приложении Phoenix см. в руководстве «Маршрутизация».

Краткое описание

Рефлексия

route_info(router, method, path, host)

Возвращает информацию о маршруте на этапе компиляции и параметры пути во время выполнения для запроса.

scoped_alias(router_module, alias)

Возвращает полный псевдоним с префиксом псевдонима текущей области.

scoped_path(router_module, path)

Возвращает полный путь с префиксом пути текущей области.

Функции

connect(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки CONNECT-запроса к заданному пути.

delete(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки DELETE-запроса к заданному пути.

forward(path, plug, plug_opts \\ [], router_opts \\ [])

Перенаправляет запрос по заданному пути к плагину.

get(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки GET-запроса к заданному пути.

head(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки HEAD-запроса к заданному пути.

match(verb, path, plug, plug_opts, options \\ [])

Создаёт сопоставление маршрута на основе произвольного HTTP-метода.

options(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки OPTIONS-запроса к заданному пути.

patch(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки PATCH-запроса к заданному пути.

pipe_through(pipes)

Определяет список плагинов (и конвейеров), через которые проходит соединение.

pipeline(plug, list)

Определяет конвейер плагинов.

plug(plug, opts \\ [])

Определяет плагин внутри конвейера.

post(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки POST-запроса к заданному пути.

put(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки PUT-запроса к заданному пути.

resources(path, controller)

См. resources/4.

resources(path, controller, opts)

См. resources/4.

resources(path, controller, opts, list)

Определяет «RESTful»-маршруты для ресурса.

routes(router)

Возвращает сведения обо всех маршрутах заданного маршрутизатора.

scope(options, list)

Определяет область, внутри которой можно вкладывать маршруты.

scope(path, options, list)

Определяет область с заданным путём.

scope(path, alias, options, list)

Определяет область с заданными путём и псевдонимом.

trace(path, plug, plug_opts, options \\ [])

Создаёт маршрут для обработки TRACE-запроса к заданному пути.

Рефлексия

route_info(router, method, path, host)Исходный код

Возвращает информацию о маршруте на этапе компиляции и параметры пути во время выполнения для запроса.

Значение path может быть строкой или сегментами path_info.

Возвращается карта метаданных со следующими ключами:

  • :log — настроенный уровень журналирования. Например, :debug
  • :path_params — карта параметров пути во время выполнения
  • :pipe_through — список конвейеров для области маршрута, например [:browser]
  • :plug — плагин, которому передаётся маршрут, например AppWeb.PostController
  • :plug_opts — параметры, передаваемые при вызове плагина, например: :index
  • :route — строковый шаблон маршрута, например "/posts/:id"

Примеры

iex> Phoenix.Router.route_info(AppWeb.Router, "GET", "/posts/123", "myhost")
%{
  log: :debug,
  path_params: %{"id" => "123"},
  pipe_through: [:browser],
  plug: AppWeb.PostController,
  plug_opts: :show,
  route: "/posts/:id",
}

iex> Phoenix.Router.route_info(MyRouter, "GET", "/not-exists", "myhost")
:error

scoped_alias(router_module, alias)Исходный код

Возвращает полный псевдоним с префиксом псевдонима текущей области.

Полезно для применения той же сокращённой обработки псевдонимов к значениям, отличным от второго аргумента в определениях маршрутов.

Примеры

scope "/", MyPrefix do
  get "/", ProxyPlug, controller: scoped_alias(__MODULE__, MyController)
end

scoped_path(router_module, path)Исходный код

Возвращает полный путь с префиксом пути текущей области.

Функции

connect(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки connect-запроса по указанному пути.

connect("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

delete(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки delete-запроса по указанному пути.

delete("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

forward(path, plug, plug_opts \\ [], router_opts \\ [])Источник

Перенаправляет запрос по указанному пути в plug.

Чаще всего это используется для перенаправления всех вложенных маршрутов в другой Plug. Например:

forward "/admin", SomeLib.AdminDashboard

Это позволит SomeLib.AdminDashboard обрабатывать /admin, /admin/foo, /admin/bar/baz и так далее. Кроме того, SomeLib.AdminDashboard не нужно знать префикс, с которым он подключён. С его точки зрения, указанные выше маршруты обрабатываются как /, /foo и /bar/baz.

Обычный сценарий использования forward — совместное использование маршрутизатора несколькими приложениями или разделение большого маршрутизатора на несколько меньших. Однако для корректной генерации маршрутов можно перенаправить запросы только в один экземпляр Phoenix.Router.

Перед перенаправлением соединения будут выполнены конвейеры маршрутизатора.

Примеры

scope "/", MyApp do
  pipe_through [:browser, :admin]

  forward "/admin", SomeLib.AdminDashboard
  forward "/api", ApiRouter
end

get(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки get-запроса по указанному пути.

get("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

head(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки head-запроса по указанному пути.

head("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

Совместимость с Plug.Head

По умолчанию приложения Phoenix включают Plug.Head в свою конечную точку, где HEAD-запросы преобразуются в обычные GET-запросы. Поэтому, если вы хотите использовать head/4 в маршрутизаторе, необходимо переместить Plug.Head внутрь маршрутизатора так, чтобы он не конфликтовал с путями, указанными в head/4.

match(verb, path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут, соответствующий произвольному методу HTTP.

Полезно для определения маршрутов, не включённых во встроенные макросы.

Также можно использовать универсальный метод :* для сопоставления со всеми методами HTTP.

Параметры

  • :as — задаёт именованный helper. Если указано nil, helper не создаётся. Не действует, если используются только проверяемые маршруты
  • :alias — определяет, следует ли применять к маршруту псевдоним области видимости. По умолчанию — true; если задано false, область видимости не применяется.
  • :log — уровень журналирования диспетчеризации маршрута; можно задать false. По умолчанию — :debug. Запись диспетчеризации содержит сведения об обработке маршрута (какое действие контроллера вызывается, какие параметры доступны и какие конвейеры используются) и ведётся отдельно от журналирования на уровне plug. Чтобы изменить уровень журналирования plug, см. https://phoenix.hexdocs.pm/Phoenix.Logger.html#module-dynamic-log-level.
  • :private — карта приватных данных, добавляемых к соединению при совпадении маршрута
  • :assigns — карта данных, добавляемых к соединению при совпадении маршрута
  • :metadata — карта метаданных, используемых событиями telemetry и возвращаемых функцией route_info/4. Поле :mfa используется telemetry для вывода журналов, а маршрутизатором — для выполнения проверок во время компиляции. Можно добавлять пользовательские поля.
  • :warn_on_verify — логическое значение, определяющее, будет ли совпадение с этим маршрутом вызывать предупреждение о несопоставленном маршруте для Phoenix.VerifiedRoutes. Это позволяет исключить из проверки маршрутов совпадение с определением маршрута, которое в противном случае охватывало бы все случаи. По умолчанию — false.

Примеры

match(:move, "/events/:id", EventController, :move)

match(:*, "/any", SomeController, :any)

options(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки options-запроса по указанному пути.

options("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

patch(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки patch-запроса по указанному пути.

patch("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

pipe_through(pipes)Источник

Определяет список plug (и конвейеров), через которые проходит соединение.

Plug указываются атомарным именем любой импортированной функции с арностью 2, которая принимает Plug.Conn и параметры и возвращает Plug.Conn. Например, :require_authenticated_user.

Конвейеры определяются в маршрутизаторе; дополнительную информацию см. в разделе pipeline/2.

pipe_through [:require_authenticated_user, :my_browser_pipeline]

Несколько вызовов

Функцию pipe_through/1 можно вызывать несколько раз в одной области видимости. Каждый вызов добавляет новые plug и конвейеры, которые будут применяться ко всем маршрутам, определённым после вызова pipe_through/1. Например:

scope "/" do
  pipe_through [:browser]
  get "/", HomeController, :index

  pipe_through [:require_authenticated_user]
  get "/settings", UserController, :edit
end

В примере выше / проходит только через browser, а /settings — через browser и require_authenticated_user. Поэтому, чтобы избежать путаницы, рекомендуем использовать один pipe_through в начале каждой области видимости:

scope "/" do
  pipe_through [:browser]
  get "/", HomeController, :index
end

scope "/" do
  pipe_through [:browser, :require_authenticated_user]
  get "/settings", UserController, :edit
end

pipeline(plug, list)Источник

Определяет конвейер plug.

Конвейеры определяются в корне маршрутизатора и могут использоваться из любой области видимости.

Примеры

pipeline :api do
  plug :token_authentication
  plug :dispatch
end

Затем область видимости может использовать этот конвейер следующим образом:

scope "/" do
  pipe_through :api
end

При каждом вызове pipe_through/1 новые конвейеры добавляются к указанным ранее.

plug(plug, opts \\ [])Источник

Определяет plug внутри конвейера.

Дополнительную информацию см. в разделе pipeline/2.

post(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки post-запроса по указанному пути.

post("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

put(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки put-запроса по указанному пути.

put("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

resources(path, controller)Источник

См. resources/4.

resources(path, controller, opts)Источник

См. resources/4.

resources(path, controller, opts, list)Источник

Определяет маршруты «RESTful» для ресурса.

Указанное определение:

resources "/users", UserController

будет включать маршруты для следующих действий:

  • GET /users => :index
  • GET /users/new => :new
  • POST /users => :create
  • GET /users/:id => :show
  • GET /users/:id/edit => :edit
  • PATCH /users/:id => :update
  • PUT /users/:id => :update
  • DELETE /users/:id => :delete

Параметры

Этот макрос принимает набор параметров:

  • :only — список действий, для которых нужно создать маршруты, например: [:show, :edit]
  • :except — список действий, для которых не нужно создавать маршруты, например: [:delete]
  • :param — имя параметра этого ресурса; по умолчанию — "id"
  • :name — префикс этого ресурса. Используется для именованного helper и как префикс параметра во вложенных ресурсах. Значение по умолчанию автоматически определяется по имени контроллера: например, UserController будет иметь имя "user"
  • :as — задаёт именованный helper. Если указано nil, helper не создаётся. Не действует, если используются только проверяемые маршруты
  • :singleton — определяет маршруты для одиночного ресурса, который клиент запрашивает без указания идентификатора. Подробнее см. ниже

Одиночные ресурсы

Если ресурс нужно запрашивать без указания идентификатора, поскольку в заданном контексте он содержит только одну запись, можно использовать параметр :singleton, чтобы создать набор маршрутов для такого одиночного ресурса:

  • GET /user => :show
  • GET /user/new => :new
  • POST /user => :create
  • GET /user/edit => :edit
  • PATCH /user => :update
  • PUT /user => :update
  • DELETE /user => :delete

Пример использования:

resources "/account", AccountController, only: [:show], singleton: true

Вложенные ресурсы

Этот макрос также поддерживает передачу вложенного блока определений маршрутов. Это удобно для вложения дочерних ресурсов в родительские и создания вложенных маршрутов.

Указанное определение:

resources "/users", UserController do
  resources "/posts", PostController
end

будет включать следующие маршруты:

user_post_path  GET     /users/:user_id/posts           PostController :index
user_post_path  GET     /users/:user_id/posts/:id/edit  PostController :edit
user_post_path  GET     /users/:user_id/posts/new       PostController :new
user_post_path  GET     /users/:user_id/posts/:id       PostController :show
user_post_path  POST    /users/:user_id/posts           PostController :create
user_post_path  PATCH   /users/:user_id/posts/:id       PostController :update
                PUT     /users/:user_id/posts/:id       PostController :update
user_post_path  DELETE  /users/:user_id/posts/:id       PostController :delete

routes(router)Источник

Возвращает сведения обо всех маршрутах указанного маршрутизатора.

scope(options, list)Источник

Определяет область видимости, внутри которой можно размещать вложенные маршруты.

Примеры

scope path: "/api/v1", alias: API.V1 do
  get "/pages/:id", PageController, :show
end

Созданный маршрут будет соответствовать пути "/api/v1/pages/:id" и направлять запрос к действию :show в API.V1.PageController. Также будет создан именованный helper api_v1_page_path.

Параметры

Поддерживаются следующие параметры:

  • :path — строка, содержащая область видимости пути.
  • :as — строка или атом, содержащие область видимости именованного helper. Если задано false, сбрасывает вложенные области видимости helper. Не действует, если используются только проверяемые маршруты
  • :alias — псевдоним (атом), содержащий область видимости контроллера. Если задано false, сбрасывает все вложенные псевдонимы.
  • :host — строка или список строк, содержащих область видимости хоста либо префикс области видимости хоста, например "foo.bar.com", "foo."
  • :private — карта приватных данных, добавляемых к соединению при совпадении маршрута
  • :assigns — карта данных, добавляемых к соединению при совпадении маршрута
  • :log — уровень журналирования диспетчеризации маршрута; можно задать false. По умолчанию — :debug. Запись диспетчеризации содержит сведения об обработке маршрута (какое действие контроллера вызывается, какие параметры доступны и какие конвейеры используются) и ведётся отдельно от журналирования на уровне plug. Чтобы изменить уровень журналирования plug, см. https://phoenix.hexdocs.pm/Phoenix.Logger.html#module-dynamic-log-level.

scope(path, options, list)Источник

Определяет область видимости с указанным путём.

Эта функция является сокращённой записью для:

scope path: path do
  ...
end

Примеры

scope "/v1", host: "api." do
  get "/pages/:id", PageController, :show
end

scope(path, alias, options, list)Источник

Определяет область видимости с указанными путём и псевдонимом.

Эта функция является сокращённой записью для:

scope path: path, alias: alias do
  ...
end

Примеры

scope "/v1", API.V1, host: "api." do
  get "/pages/:id", PageController, :show
end

trace(path, plug, plug_opts, options \\ [])Источник

Создаёт маршрут для обработки trace-запроса по указанному пути.

trace("/events/:id", EventController, :action)

Сведения о параметрах см. в разделе match/5.

Пакет Hex Предпросмотр Hex Скачать версию ePub

Создано с помощью ExDoc (v0.40.3) для языка программирования Elixir

© 2014 Chris McCord
Licensed under the MIT License.
https://phoenix.hexdocs.pm/Phoenix.Router.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API