在大型 Laravel 应用程序中管理路由
发布时间 作者 史蒂夫·麦克杜格尔
Laravels 路由文件可能变得非常繁忙。不知不觉中,您必须在路由文件中搜索才能找到任何内容。但是如何解决这个问题呢?
您可以通过多种方法来解决这个问题,具体取决于您希望如何处理。在本教程中,我将介绍一些我见过的选项,然后介绍我如何解决这个问题以及为什么这样做。
我将使用一个简单的例子,但您可以发挥您的想象力!假设我们正在构建一个 API 应用程序,它允许客户从目录在线订购商品,并允许他们的客户跟踪货运。
路由服务提供者
使用路由服务提供者,您可以轻松添加额外的路由条目。让我们看一个例子
class RouteServiceProvider extends ServiceProvider{ public function boot(): void { $this->configureRateLimiting(); $this->routes(function (): void { Route::middleware('api') ->group(base_path('routes/api.php')); }); }}
这类似于您在 Laravel 项目中获得的默认 RouteServiceProvider
。您的服务提供者可能因应用程序的版本而异。我们如何扩展它?我们可以在提供者中添加额外的路由加载
class RouteServiceProvider extends ServiceProvider{ public function boot(): void { $this->configureRateLimiting(); $this->routes(function (): void { Route::middleware('api') ->group(base_path('routes/api.php')); Route::middleware('api') ->group(base_path('routes/resource/catalog.php')); Route::middleware('api') ->group(base_path('routes/resource/orders.php')); Route::middleware('api') ->group(base_path('routes/resource/payments.php')); Route::middleware('api') ->group(base_path('routes/resource/deliveries.php')); }); }}
这不是为了完全准确。我更多的是将其用作一个例子,其中包含几个可能至少包含 75 个以上路由的活动部件。因此,我们在这里在 RouteServiceProvider
中管理它,以便我们在加载路由的方式上保持一致。我发现这种方法最大的问题是,当在路由文件中时,您需要知道加载了哪些其他内容。我之前在一个使用这种方法的非常大的应用程序上工作过,这需要大量的脑力,才能不断地回过头来看看路由是否正在加载,以及它们是否按照可能导致问题的顺序加载。
当您第一次打开一个 Laravel 项目时,您会关注几个关键区域:Eloquent 模型、路由和测试。您打开路由文件并查看注册的路由,以了解应用程序的大小以及如何构建应用程序。
需要文件
如果您安装 Laravel Breeze,您会注意到它会将以下内容添加到您的 routes/web.php
文件中
require __DIR__ . '/auth.php';
这会加载与软件包一起提供的身份验证路由,使您的服务提供者更简洁,并了解需要检查多少个额外的文件才能查看所有路由。让我们使用上面的例子,并通过这种方法添加路由
// The rest of your `routes/api.php` file require __DIR__ . '/resource/catalog.php';require __DIR__ . '/resource/orders.php';require __DIR__ . '/resource/payments.php';require __DIR__ . '/resource/deliveries.php';
对我来说,这比服务提供者方法有所改进,因为当您遍历路由文件时,您可能会在应用程序中获得更好的可见性。但是,我讨厌看到需要文件。这感觉很乱,很懒惰。
好处是,您可以在一个您期望看到路由的简单位置查看加载所有路由所需的必要内容。但是,缺点是,它只是一种需要的方法,在执行此脚本时加载文件。
对我来说,这可以得到很大的改进。这里没有信息说明 URL 结构可能是什么样子,或者您知道应用于所有路由的任何附加中间件。
路由组
这是我喜欢的做法。我们看到它们被用于 RouteServiceProvider
中,这就是我从那里得到这个想法的。这里的基本原理是,在您的主路由文件(在本例中为 routes/api.php
)中,我们像手动添加路由一样构建路由组,然后告诉该组它需要使用单独的文件。
// The rest of your `routes/api.php` file Route::prefix('catalog')->as('catalog:')->middleware(['auth:sanctum'])->group( base_path('routes/resources/catalog.php'),); Route::prefix('orders')->as('orders:')->middleware(['auth:sanctum'])->group( base_path('routes/resources/orders.php'),); Route::prefix('payments')->as('payments:')->middleware(['auth:sanctum'])->group( base_path('routes/resources/payments.php'),); Route::prefix('deliveries')->as('deliveries:')->middleware(['auth:sanctum'])->group( base_path('routes/resources/deliveries.php'),);
如上所示,我们只是使用 base_path
辅助函数在正确的位置加载路由。查看路由文件,我们可以看到正在构建应用程序的组,但它并没有占用整个文件 - 即使您最终获得了 20-30 个组,它仍然非常易读。
从这里开始,我们可以在专用路由文件中管理“资源”和“子资源”,这意味着在导入时需要更少的类名类,并且拥有专用的文件,您可以轻松地单独或在整个应用程序的内容中理解这些文件。
您如何解决大型路由文件带来的认知负荷?您是否发现了想要分享的有趣方法?请在 Twitter 上告诉我们。