路由基础 #
一、路由概述 #
1.1 什么是路由 #
路由是将HTTP请求映射到控制器动作的机制。Phoenix路由器负责匹配请求并调用相应的处理函数。
text
HTTP请求 → Router → Controller → Response
1.2 路由文件位置 #
elixir
defmodule HelloWeb.Router do
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
end
end
二、基本路由定义 #
2.1 HTTP方法 #
Phoenix支持所有标准HTTP方法:
elixir
scope "/", HelloWeb do
pipe_through :browser
get "/users", UserController, :index
post "/users", UserController, :create
put "/users/:id", UserController, :update
patch "/users/:id", UserController, :update
delete "/users/:id", UserController, :delete
options "/users", UserController, :options
head "/users", UserController, :head
end
2.2 路由结构 #
elixir
get "/path", ControllerModule, :action_name
| 部分 | 说明 |
|---|---|
| get | HTTP方法 |
| “/path” | URL路径 |
| ControllerModule | 控制器模块 |
| :action_name | 动作函数名 |
2.3 路由示例 #
elixir
defmodule HelloWeb.Router do
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :protect_from_forgery
end
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
get "/about", PageController, :about
get "/contact", PageController, :contact
end
end
三、资源路由 #
3.1 RESTful资源 #
elixir
scope "/", HelloWeb do
pipe_through :browser
resources "/users", UserController
end
这会生成以下路由:
| HTTP方法 | 路径 | 控制器动作 | 说明 |
|---|---|---|---|
| GET | /users | UserController.index | 列表 |
| GET | /users/new | UserController.new | 新建表单 |
| POST | /users | UserController.create | 创建 |
| GET | /users/:id | UserController.show | 详情 |
| GET | /users/:id/edit | UserController.edit | 编辑表单 |
| PUT | /users/:id | UserController.update | 更新 |
| PATCH | /users/:id | UserController.update | 更新 |
| DELETE | /users/:id | UserController.delete | 删除 |
3.2 限制资源动作 #
elixir
resources "/users", UserController, only: [:index, :show]
resources "/posts", PostController, except: [:delete]
resources "/comments", CommentController, only: [:create, :update, :delete]
3.3 资源选项 #
elixir
resources "/posts", PostController do
resources "/comments", CommentController
end
resources "/photos", PhotoController, param: "slug"
四、作用域 #
4.1 基本作用域 #
elixir
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
end
4.2 带路径前缀的作用域 #
elixir
scope "/admin", HelloWeb do
pipe_through :browser
get "/dashboard", AdminController, :dashboard
resources "/users", Admin.UserController
end
生成的路由:
| 路径 | 控制器 |
|---|---|
| /admin/dashboard | HelloWeb.AdminController |
| /admin/users | HelloWeb.Admin.UserController |
4.3 带模块前缀的作用域 #
elixir
scope "/api", HelloWeb.Api, as: :api do
pipe_through :api
resources "/users", UserController
end
生成的路径辅助函数:
elixir
~p"/api/users"
api_user_path(conn, :index)
4.4 嵌套作用域 #
elixir
scope "/admin", HelloWeb.Admin, as: :admin do
pipe_through [:browser, :admin]
get "/", DashboardController, :index
scope "/users" do
resources "/", UserController, only: [:index, :show]
end
end
五、管道 #
5.1 管道定义 #
elixir
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
5.2 使用管道 #
elixir
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
end
scope "/api", HelloWeb do
pipe_through :api
resources "/users", UserController
end
5.3 多个管道 #
elixir
scope "/admin", HelloWeb.Admin do
pipe_through [:browser, :admin_auth]
resources "/users", UserController
end
六、路径辅助函数 #
6.1 自动生成的辅助函数 #
elixir
resources "/users", UserController
生成以下辅助函数:
elixir
user_path(conn, :index)
user_path(conn, :show, user.id)
user_path(conn, :new)
user_path(conn, :create)
user_path(conn, :edit, user.id)
user_path(conn, :update, user.id)
user_path(conn, :delete, user.id)
6.2 使用~p宏 #
elixir
~p"/users"
~p"/users/#{user.id}"
~p"/users/#{user.id}/edit"
6.3 URL生成 #
elixir
user_url(conn, :index)
user_url(conn, :show, user.id)
Routes.user_path(conn, :index)
Routes.user_url(conn, :index)
七、路由约束 #
7.1 参数约束 #
elixir
get "/posts/:id", PostController, :show, assigns: %{id: ~r/^\d+$/}
7.2 自定义约束 #
elixir
defmodule HelloWeb.Plugs.AdminConstraint do
def init(opts), do: opts
def call(conn, _opts) do
if admin?(conn) do
conn
else
conn
|> Plug.Conn.send_resp(403, "Forbidden")
|> Plug.Conn.halt()
end
end
defp admin?(conn) do
conn.assigns[:current_user].role == "admin"
end
end
八、转发 #
8.1 转发到其他模块 #
elixir
scope "/", HelloWeb do
pipe_through :browser
forward "/health", HealthCheck
forward "/metrics", MetricsExporter
end
8.2 转发示例 #
elixir
defmodule HelloWeb.HealthCheck do
def init(opts), do: opts
def call(conn, _opts) do
conn
|> Plug.Conn.put_resp_content_type("text/plain")
|> Plug.Conn.send_resp(200, "OK")
end
end
九、路由查看 #
9.1 查看所有路由 #
bash
mix phx.routes
输出:
text
page_path GET / HelloWeb.PageController :home
user_path GET /users HelloWeb.UserController :index
user_path GET /users/:id HelloWeb.UserController :show
user_path GET /users/new HelloWeb.UserController :new
user_path POST /users HelloWeb.UserController :create
9.2 过滤路由 #
bash
mix phx.routes HelloWeb.Router user
十、路由最佳实践 #
10.1 组织路由 #
elixir
defmodule HelloWeb.Router do
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :protect_from_forgery
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", HelloWeb do
pipe_through :browser
get "/", PageController, :home
resources "/posts", PostController
end
scope "/api", HelloWeb.Api, as: :api do
pipe_through :api
resources "/users", UserController
resources "/posts", PostController
end
end
10.2 命名约定 #
elixir
resources "/users", UserController
resources "/posts", PostController
resources "/comments", CommentController
scope "/admin", HelloWeb.Admin, as: :admin do
resources "/users", UserController
end
十一、总结 #
11.1 核心概念 #
| 概念 | 说明 |
|---|---|
| get/post/put/delete | HTTP方法路由 |
| resources | RESTful资源路由 |
| scope | 路由作用域 |
| pipeline | 请求处理管道 |
| pipe_through | 应用管道 |
| ~p | 路径宏 |
11.2 下一步 #
现在你已经了解了路由基础,接下来让我们学习 路由参数,深入了解参数处理!
最后更新:2026-03-28