Route Forge for Laravel

在 Vue / React / Inertia 单页应用(SPA)里直接使用 Laravel 的命名路由——不必硬编码 URL,也不必把整张路由表打包给前端。

Route Forge 通过一个轻量的 HTTP 元信息端点把 Laravel 的命名路由暴露出去,支持按层级(tier)拆分并按需懒加载,并生成 TypeScript 类型,让前端的路由名与参数都具备类型安全。它零注解即可工作——直接读取 Laravel 自己的路由注册表。

Latest Version on Packagist Total Downloads PHP Laravel Tests License

语言 / Language: English · 简体中文

面向 AI 助手 / 编码 Agent: 本包为 route-forge/laravel。机器可读概览见 llms.txt,Agent 集成指南见 AGENTS.md(英文)。

解决什么问题

当 Laravel 后端由一个 SPA(Vue / React / Inertia / 独立部署的移动端 Web)承接时,前端需要拼接指向后端接口的 URL。常见做法各有各的痛:

Route Forge 让后端路由表成为单一事实来源(single source of truth):前端在运行时按层级、按需获取它需要的东西,并从权威路由注册表直接生成 TypeScript 类型。

为什么选 Route Forge(能力自述)

全栈搭配: 本仓库是 route-forge 项目的后端那一半。搭配配套前端 SDK @route-forge/core(以及 @route-forge/vue / @route-forge/react),可获得请求封装、并发控制与登录态感知的层级加载。

功能概览

Route Forge 提供多种可互换、可组合的层级分配方式。层级名完全由你定义——包本身不预设任何固定层级。

  1. ->tier()——定义路由时显式标记,链式调用,对资源路由同样生效。
  2. Route::grouptier 选项——整组继承层级,嵌套 group 内层覆盖外层。
  3. 链式 Route::tier(...)->group(...)——第 2 种的流式写法,可与 middleware / prefix / as 任意顺序组合。
  4. 配置驱动的批量分配——config/forge.php 按 URI 前缀 / 中间件(any / all / DNF 数组匹配)批量归类。

此外还包括:

环境要求

安装

composer require route-forge/laravel

# 发布配置文件(可选,默认配置开箱可用)
php artisan vendor:publish --tag=forge-config

ServiceProvider 通过 Laravel 包发现自动注册。

快速上手

分配层级

// 方式一:显式标记
Route::post('/auth/login', [AuthController::class, 'login'])
    ->name('auth.login')
    ->tier('public');

// 方式二:分组继承(数组语法)
Route::group([
    'prefix'     => 'admin',
    'middleware' => ['auth', 'admin'],
    'tier'       => 'admin',
], function () {
    Route::get('/users', [AdminUserController::class, 'index'])
         ->name('admin.users.index');
});

// 方式三:链式语法(tier 可与任意路由属性、任意顺序组合)
Route::middleware(['auth', 'admin'])->tier('admin')->prefix('admin')->group(function () {
    Route::get('/users', [AdminUserController::class, 'index'])
         ->name('admin.users.index');
});

// 方式四:配置批量匹配(config/forge.php)
// 'admin' => [
//     'match' => ['prefix' => ['admin'], 'middleware' => ['auth', 'admin']],
//     'load'  => 'lazy',
// ],

⚠️ 组级属性必须在 group() 之前声明。 Route::group([...], fn)->tier('admin') 这类写法不会生效——Laravel 的 group() 在返回前 已完成组内路由注册并将组属性出栈,其后的链式调用无法回溯到这些路由。 正确写法二选一:数组语法 Route::group(['tier' => 'admin', ...], fn), 或前置链式 Route::tier('admin')->group(fn)

前端拉取元信息

GET /_forge/routes              # 摘要:所有层级(含特殊层级 unassigned)+ 全局配置 + schemeVersion
GET /_forge/routes/admin        # admin 层级下所有命名路由的元信息
GET /_forge/routes/unassigned   # 未命中任何层级的路由元信息
// 初始化:发现可用层级
const summary = await fetch('/_forge/routes').then(r => r.json());
// 按需:只加载需要的层级
const adminRoutes = await fetch('/_forge/routes/admin').then(r => r.json());

可选:把摘要内嵌进首页

如果你的前端 HTML 由 Laravel(Blade)服务端渲染,可以用 @forgeSummary 彻底省掉首屏那次摘要往返。把它放进 <head>(早于前端 bundle),它会以一次性、消费即自删、不可枚举window.__ROUTE_FORGE__ 访问器把摘要端点的返回值内嵌进页面,@route-forge/core 初始化时读一次即可:

<head>
    {{-- ... --}}
    @forgeSummary
</head>

它是叠加在既有端点之上的纯加速,不改变端点契约:

一次性自删访问器只缩小数据在 window 上的运行时驻留面;摘要数据仍随 HTML 源码可见,不是抗 XSS / 抗网络窃取的硬边界,切勿当作安全机制。

Artisan 命令

# 查看层级分配结果(--level 过滤、--json、--unassigned 仅看未分配)
php artisan route:forge:list

# 生成 TypeScript 类型声明(默认输出到 stdout;--out 写文件;--level / --json 可选)
php artisan route:forge:types

# 清除路由元信息缓存(--level 仅清指定层级;不传则清全部)。
# 执行 Laravel 内置的 php artisan route:clear 时也会自动连带清除。
php artisan route:forge:clear

主要配置项(config/forge.php)

类型 默认值 说明
levels array 见配置文件 层级定义表(匹配规则、加载策略)
endpoint_prefix string '/_forge/routes' 对外元信息端点前缀,同时也是摘要路由
url_prefix string|null null 应用路由前缀,经摘要端点下发;支持完整 URL 或路径前缀,空则不下发
endpoint_middleware string[] [] 摘要端点中间件;空数组或 null 不限制
cache_ttl int|null 3600 统一缓存 TTL(秒);null 不缓存,0 永久缓存,负值视为 null
cache_driver string|null null 缓存驱动;null 使用默认驱动
strict_mode bool false 未命中层级时抛异常(true)或归入 unassignedfalse
scheme_version int 1 摘要端点响应格式版本(schemeVersion
classifier callable|null null 自定义分类回调 fn(Route $r): ?string

完整配置项参考(含 levels.{name}.* 子键)见 .docs/SPEC.md §5

开发模式

APP_DEBUG=true(Laravel 本地开发默认配置)时,Route Forge 自动跳过所有缓存读写,路由变更即时生效、无需手动清缓存。生产环境(APP_DEBUG=false)默认启用缓存以提升性能。

管理器页面

开发环境下可访问可视化路由面板 GET /_forge/manager,提供:

⚠️ 仅 APP_DEBUG=true 时注册,生产环境不存在任何管理器路由。 开发环境内还受 manager_allowed_ips IP 白名单保护(默认仅 127.0.0.1 / ::1 本机可访问;局域网调试可追加开发机局域网 IP,详见 config/forge.php)。

仓库与文档

本仓库发布 route-forge/laravel composer 包(后端适配层)。框架无关核心(层级解析、别名、路由仓库、缓存、TS 类型生成)位于配套的 route-forge/common 包,随依赖自动安装;前端包(@route-forge/core@route-forge/vue@route-forge/react)在另一仓库独立维护。

开发

本包依赖框架无关核心 route-forge/common。本地开发通过不入版本库composer.local.json(path repository → ../route-forge-common)串联两个仓库;composer.json 本身保持干净,可直接发布。

# 本地开发(path repository 指向 ../route-forge-common)
COMPOSER=composer.local.json composer install
COMPOSER=composer.local.json composer update

# route-forge/common 发布到 Packagist 后,直接
composer install

composer test            # 运行 PHPUnit 测试套件
composer test:coverage   # 文本覆盖率报告

测试基于 orchestra/testbench,覆盖层级分配优先级(含资源路由)、中间件匹配(any/all/DNF)、端点响应、缓存、严格模式与三个 Artisan 命令。CI 通过 GitHub Actions 跑 PHP 8.2–8.5 × Laravel 11/12/13 版本矩阵(排除 PHP 8.2 × Laravel 13 组合,见 .github/workflows/tests.yml)。

License

MIT