13.x,框架实现参考的是最新发布版本 v13.34.0。
loadRoutesFrom 只负责加载文件
当应用程序实现了CachesRoutes 且 routesAreCached() 为真时,ServiceProvider::loadRoutesFrom() 不会加载路由文件。其他情况下,它会 require 指定的文件。
该方法本身不会添加 URI 或路由名称的前缀、控制器命名空间以及中间件。它也不会发布文件,或向现有缓存中追加路由。
图示以标准的 Laravel 应用程序为前提。并不存在包专用的缓存,包的路由也包含在整个应用程序的路由缓存中。
将配置与注册分开
下面的示例创建一个返回包是否可响应的公开端点。前提是已通过 Composer 的 PSR-4 将Acme\Courier\ 映射到 src/,并且提供者已通过自动发现或手动方式注册。
config/courier.php
register() 中进行,路由的加载在 boot() 中进行。请不要将注册 HTTP 路由的提供者设为 DeferrableProvider,因为这样就无法保证在需要路由时提供者已经启动。
src/CourierServiceProvider.php
routes/web.php
src/Http/Controllers/StatusController.php
/acme-courier/status,路由名称为 acme-courier.status。只要使用 route('acme-courier.status') 生成 URL,即使修改了 URI 前缀,调用方也可以继续使用同一个路由名称。路由组的 name() 会直接拼接字符串,因此末尾的 . 也需要指定。
web 并不能替代认证与授权。本示例是不包含敏感信息的公开端点。对于返回用户数据的端点,请根据需求另行设置认证中间件和授权处理。分别防止 URI 与路由名称的冲突
URI 前缀与路由名称前缀是两套不同的机制。只添加其中一种,无法防止另一种发生冲突。AbstractRouteCollection 在创建用于缓存的路由集合时,如果不同的路由使用了相同的名称,会抛出 LogicException。“正常启动时能够生成 URL”并不能保证可以缓存。即使是 URI 不同的两个路由,只要名称相同也会出现问题。
请不要把通过注册顺序覆盖使用方应用程序的路由作为包的扩展方式。如有需要,应提供禁用路由的配置,以及用户可以从其他路由调用的服务。
创建缓存时的配置会保留在路由定义中
RouteCacheCommand 会先执行 route:clear,然后启动一个新的应用程序来收集路由。接着将这些路由准备为可序列化的形式,并把编译结果写入缓存文件。
此时包的路由文件也会被加载,因此前缀以及是否注册由创建缓存时的配置决定。之后的启动中,loadRoutesFrom() 不会加载文件,而是使用已缓存的路由。
请不要根据用户或租户等每个请求都会变化的条件来注册路由。这些条件会在创建缓存时的 CLI 环境中求值。路由应以稳定的结构注册,是否允许访问则由中间件或控制器内的授权来判断。
部署时先确定配置
在完成代码与配置的更新后,对于使用配置缓存的结构,请按以下顺序重新创建。请将其纳入使用方应用程序的部署流程。route:cache,路由也会基于旧配置创建。仅重新执行 config:cache 并不会更新路由缓存。通过 -vv 还可以确认中间件组的内容。
在开发过程中需要在无缓存的状态下确认行为时,请根据需要同时清除两者。
发布前需要确认的组合
除了包的测试之外,还需要在 Laravel 13 的使用方应用程序中确认以下组合。不仅要覆盖内存中的路由注册,也要覆盖 Artisan 启动新应用程序的路径。- 无缓存时
/acme-courier/status能够响应,且路由名称与中间件符合预期。 route:cache执行成功,在新的启动中也以相同的 URI 和路由名称响应。- 修改前缀并重新创建缓存后,新的 URI 能够响应,旧 URI 上的包路由不再存在。
- 禁用并重新创建缓存后,
route:list --name=acme-courier中不再显示目标路由。 - 与使用方应用程序或其他包之间不存在 URI 或路由名称的冲突。
相关页面
路由
了解路由组、命名路由和列表显示的基础知识。
包配置的合并与缓存
了解兼顾已发布配置和配置缓存的更新步骤。
延迟 Service Provider
了解为什么不应延迟注册路由的提供者。
包的版本兼容性管理
将公开 API 的变更与发布策略和持续验证关联起来。