3.1 路由定义、分组与资源路由


3.1 路由定义、分组与资源路由

本节摘要:路由是把 URI 与处理代码对应起来的登记簿。本节给出一份完整的注册语料库:基本定义、参数与正则约束、命名路由、分组共享配置,以及一行注册七个 RESTful 动作的资源路由;最后讲路由缓存这件容易忘的事。读完你能把一个项目的全部入口写得一眼可读。

接单窗口的第一本账

上一章的流水线里,请求穿过全局中间件后就到了路由匹配这一站。本节要做的就是写好这本登记簿。判断一本登记簿好不好,标准很朴素:新同事打开 routes 目录,五分钟内能说出这个项目对外有多少入口、各归谁管。所有语法糖都为这个目标服务。

基本定义与参数

<?php // routes/web.php use App\Http\Controllers\WorkOrderController; use Illuminate\Support\Facades\Route; // 最基本:URI 对应闭包或控制器动作 Route::get('/welcome', function () { return '工地开放日'; }); // 路由参数:花括号占位,可选参数加问号 Route::get('/orders/{id}/comments/{commentId?}', [WorkOrderController::class, 'comments']); // 参数约束:格式不对直接 404,不劳控制器操心 Route::get('/orders/{id}', [WorkOrderController::class, 'show']) ->whereNumber('id') ->name('orders.show'); Route::get('/archive/{month}', function (string $month) { return "归档:{$month}"; })->where('month', '[0-9]{4}-[0-9]{2}');

两个习惯值得从第一天养成。其一,凡是会在代码里跳转或生成的路由都起名字,之后 route('orders.show', ['id' => 5]) 随处可用,URI 改了业务代码不用动。其二,能用 whereNumber、whereUuid 这类内置约束就不要手写正则——约束前移到进件口,非法请求根本进不了车间。

分组:一份配置管一批路由

真实项目的路由很少零散登记,多数按"前缀、中间件、目录"三个维度成组。分组可以嵌套,共享配置自动向下传递:

<?php // 后台工单模块:同一个前缀、同一道门卫、同一个控制器目录 Route::middleware(['auth']) ->prefix('admin') ->name('admin.') ->group(function () { Route::get('/dashboard', [AdminDashboardController::class, 'index']) ->name('dashboard'); // 最终名字是 admin.dashboard Route::get('/orders', [AdminOrderController::class, 'index']) ->name('orders.index'); Route::get('/orders/{order}/accept', [AdminOrderController::class, 'accept']) ->name('orders.accept'); });

这一组读下来信息完整:这批入口都要登录(auth 门卫),URI 都带 admin 前缀,名字都以 admin. 开头。分组嵌套时外层管共性、内层管个性,比如外层套 auth,内层再套一个"仅管理员"的门卫——这正是第三章第三节的主题。

资源路由:一行注册七个动作

RESTful 的订单模块,标准动作无非增删改查加列表加表单页。资源路由把它们一次登记完:

<?php use App\Http\Controllers\OrderController; // 一行顶七条:index、create、store、show、edit、update、destroy Route::resource('orders', OrderController::class); // 只要其中几个,或排除某几个 Route::resource('orders', OrderController::class) ->only(['index', 'show', 'store']) ->except(['destroy']); // API 版资源:去掉 create 与 edit 两个页面动作 Route::apiResource('orders', OrderController::class);
动作 URI 方法 名字 用途
index /orders GET orders.index 列表页
create /orders/create GET orders.create 新建表单页
store /orders POST orders.store 保存新建
show /orders/{order} GET orders.show 详情页
edit /orders/{order}/edit GET orders.edit 编辑表单页
update /orders/{order} PUT 或 PATCH orders.update 保存修改
destroy /orders/{order} DELETE orders.destroy 删除

⚠️ 常见坑:资源路由默认不带登录门卫。生产代码里请给它套上 middleware 分组;另外 show 与 update 共用同一个参数名 {order},这正好给下一节的路由模型绑定留了位。

图 3-1:一张工单在进件窗口的分流路径

图 3-1:一张工单在进件窗口的分流路径

路由缓存:别忘了这件收尾活

路由一多,每次请求都重新扫描登记簿就浪费了。php artisan route:cache 把整本登记簿编译成单文件数组,匹配从遍历文件变成查数组。两条纪律:只在生产环境跑缓存(缓存后只认控制器路由,闭包路由会直接报错);改了路由文件必须 route:clear 或重新 cache,否则线上一直跑旧账。排查"路由明明改了为什么不生效",第一件事就是清路由缓存。

本节要点回顾

  • 登记三形态:闭包管临时入口,控制器管正席,资源路由管成套 RESTful 工位。
  • 参数两件事:花括号收参、where 系约束拦非法,名字用 name 起好供全项目引用。
  • 分组共享:前缀、门卫、命名前缀成组传递,嵌套时外共性内个性。
  • 缓存纪律:生产 route:cache、闭包不进缓存、改账必清缓存。

登记簿写好了,下一节解决一个更细的问题:URL 里的那个编号,怎么安全地变成数据库里的模型对象。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U