Phoenix (Elixir)JuniorTechnical
Как работает маршрутизация (routing) в Phoenix? Что такое Router?
Phoenix Router определяет маршруты через DSL: resources, get/post/put/delete, scope для группировки, pipeline для middleware. Router компилируется в эффективный pattern matching Elixir.
Что такое Phoenix Router
Phoenix Router — модуль, который отображает HTTP-запросы (метод + путь) на контроллеры и LiveView. Он компилируется в оптимальный Elixir pattern matching, что даёт O(1) dispatch без runtime overhead.
Базовая структура Router
defmodule MyappWeb.Router do
use MyappWeb, :router
# Pipeline — набор plug-ов для группы маршрутов
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, html: {MyappWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
# Группа маршрутов с pipeline
scope "/", MyappWeb do
pipe_through :browser
get "/", PageController, :home
get "/about", PageController, :about
end
scope "/api", MyappWeb do
pipe_through :api
get "/health", HealthController, :check
resources "/users", UserController, only: [:index, :show, :create]
end
end
REST resources — RESTful маршруты одной строкой
resources "/posts", PostController
# Генерирует:
# GET /posts :index
# GET /posts/new :new
# POST /posts :create
# GET /posts/:id :show
# GET /posts/:id/edit :edit
# PUT /posts/:id :update
# PATCH /posts/:id :update
# DELETE /posts/:id :delete
# Ограничение набора экшенов
resources "/articles", ArticleController, only: [:index, :show]
resources "/sessions", SessionController, except: [:new, :edit]
# Вложенные ресурсы
resources "/posts", PostController do
resources "/comments", CommentController, only: [:index, :create]
end
# GET /posts/:post_id/comments
# POST /posts/:post_id/comments
LiveView маршруты
scope "/", MyappWeb do
pipe_through [:browser, :require_authenticated_user]
live "/dashboard", DashboardLive, :index
live "/products", ProductsLive, :index
live "/products/:id", ProductDetailLive, :show
live "/products/:id/edit", ProductDetailLive, :edit
end
Scope для версионирования API
scope "/api", MyappWeb do
pipe_through :api
scope "/v1", V1 do
resources "/users", UserController
resources "/products", ProductController
end
scope "/v2", V2 do
resources "/users", UserController # Другой модуль контроллера
end
end
Просмотр всех маршрутов
# Список всех маршрутов
mix phx.routes
# Вывод:
# GET / PageController :home
# GET /api/v1/users V1.UserController :index
# GET /api/v1/users/:id V1.UserController :show
# ...
Wildcard и forward
# Wildcard маршрут (должен быть последним!)
get "/*path", PageController, :not_found
# Forward к Plug — например Plug.Static или другому приложению
forward "/uploads", Plug.Static,
at: "/",
from: {:myapp, "priv/static/uploads"}
Подводные камни
- Порядок маршрутов важен: Phoenix матчит маршруты сверху вниз.
get "/users/export"должен быть вышеget "/users/:id", иначе "export" будет интерпретирован как :id. - pipe_through не наследуется вложенными scope: внутренний scope должен явно вызывать
pipe_through. Если хотите добавить pipeline к вложенному scope — объявите его отдельно. - resources и custom actions:
resourcesгенерирует стандартные CRUD. Для кастомных экшенов добавляйте отдельные маршруты внутри блокаresourcesили рядом. - Алиасы scope суммируются:
scope "/api", MyappWeb do+scope "/v1", V1 do— итоговый алиасMyappWeb.V1. Убедитесь, что модули существуют по полному пути. - LiveView требует :browser pipeline: LiveView использует сессии и WebSocket, которые зависят от
fetch_sessionиfetch_live_flash. Без:browserpipeline получите ошибки инициализации. - mix phx.routes показывает скомпилированные маршруты: после изменений в router нужно перекомпилировать (
mix compile) для корректного вывода. В dev-режиме это происходит автоматически при следующем запросе.
Common mistakes
- Сводить router к названию метода без lifecycle и failure path.
- Игнорировать модель runtime: Phoenix 1.8 работает поверх Plug, Endpoint, Router, Controllers/LiveViews, PubSub и OTP supervision.
- Не отделять validation, authorization, transaction boundary и business logic.
What the interviewer is testing
- Объясняет router через конкретную точку lifecycle в Phoenix (Elixir).
- Приводит корректный минимальный пример без вымышленных методов или callbacks.
- Называет edge cases: пустые значения, ошибки, транзакции, безопасность или concurrency.