Home > Article > PHP Framework > Let’s talk about how to organize routing in large Laravel projects
Imagine a Laravel project with more than 100 routes, including separate modules for visitors, users, administrators, etc. Do you really want to write everything in one file? So how do you group them and add a prefix to the URL? See what options are available.
This is simple, because Laravel has already done it for you. There are the following two files:
Therefore, if your project has both a front-end page and an API (the usage scenarios are getting wider and wider), please put the API routing in api.php. [Related recommendations: laravel video tutorial]
For example, if you have the /users page and the /api/users/ endpoint, Write them separately in their own routing files to avoid confusion caused by the same names appearing in the same file.
But I recently saw a counterexample from the Official Laravel project. In Laravel Horizon, Taylor only has API routes, but he did not write them separately. He still wrote them in routes/web.php :
Another example proves that Laravel is still very personal, and even Taylor himself does not follow the standards 100%.
The following example is also an example from Laravel official documentation:
Route::middleware(['first', 'second'])->group(function () { Route::get('/', function () { // 使用 first 和 second 中间件 }); Route::get('user/profile', function () { // 使用 first 和 second 中间件 }); });
The most basic usage is to include different routing groups in different middleware. For example, you want one group to be restricted by the auth middleware by default, another group to be restricted by a separate admin custom middleware, etc.
In this way, you can also use route grouping methods such as name and prefix. Again, the example is given in the official documentation:
Route::prefix('admin')->group(function () { Route::get('users', function () { // 匹配 URL 「/admin/users」 }); }); Route::name('admin.')->group(function () { Route::get('users', function () { // 路由名为 「admin.users」... })->name('users'); });
Also, if you want to add all middleware name prefixes to a group, it's easier to understand by putting them in an array:
// 而不是这样做: Route::name('admin.')->prefix('admin')->middleware('admin')->group(function () { // ... }); // 可以使用数组 Route::group([ 'name' => 'admin.', 'prefix' => 'admin', 'middleware' => 'auth' ], function () { // ... });
Let's combine this into a real example with three route groups:
Here's how to group everything into a routes/web.php file Method:
Route::group([ 'name' => 'admin.', 'prefix' => 'admin', 'middleware' => 'admin' ], function () { // URL链接:/admin/users // 路由名称:admin.users Route::get('users', function () { return 'Admin: user list'; })->name('users'); }); Route::group([ 'name' => 'user.', 'prefix' => 'user', 'middleware' => 'auth' ], function () { // URL链接:/user/profile // 路由名称:user.profile Route::get('profile', function () { return 'User profile'; })->name('profile'); }); Route::group([ 'name' => 'front.', 'prefix' => 'front' ], function () { // 这里没有中间件 // URL链接:/front/about-us // 路由名称:front.about Route::get('about-us', function () { return 'About us page'; })->name('about'); });
In the above example, we did not use the controller, we just returned Static text as an example. Let's add a controller and get a little fancy — we'll structure them into folders in their own different namespaces, like this:
Then we can Use them in routing files:
Route::group([ 'name' => 'front.', 'prefix' => 'front' ], function () { Route::get('about-us', 'Front.boutController@index')->name('about'); });
But what if we have many controllers in this group? Should we keep adding Front.omeController? of course not. You can also pass a namespace as one of the parameters.
Route::group([ 'name' => 'front.', 'prefix' => 'front', 'namespace' => 'Front', ], function () { Route::get('about-us', 'AboutController@index')->name('about'); Route::get('contact', 'ContactController@index')->name('contact'); });
The above situation is divided into 3 groups. In fact, this is simplified. The structure of the actual project Slightly different – there are two groups: front and auth. Then within auth, there are two subgroups: user and admin. To do this, we can create subgroups in routes/web.php and assign different middlewares/prefixes etc.
Route::group([ 'middleware' => 'auth', ], function() { Route::group([ 'name' => 'admin.', 'prefix' => 'admin', 'middleware' => 'admin' ], function () { // URL: /admin/users // Route name: admin.users Route::get('users', 'UserController@index')->name('users'); }); Route::group([ 'name' => 'user.', 'prefix' => 'user', ], function () { // URL: /user/profile // Route name: user.profile Route::get('profile', 'ProfileController@index')->name('profile'); }); });
We can even have multiple levels of nesting, which is an example of an open source project. Akaunting:
Route::group(['middleware' => 'language'], function () { Route::group(['middleware' => 'auth'], function () { Route::group(['prefix' => 'uploads'], function () { Route::get('{id}', 'Common.ploads@get'); Route::get('{id}/show', 'Common.ploads@show'); Route::get('{id}/download', 'Common.ploads@download'); }); Route::group(['middleware' => 'permission:read-admin-panel'], function () { Route::group(['prefix' => 'wizard'], function () { Route::get('/', 'Wizard.ompanies@edit')->name('wizard.index'); // ...
Another example comes from another popular Laravel CRM called Monica:
Route::middleware(['auth', 'verified', 'mfa'])->group(function () { Route::name('dashboard.')->group(function () { Route::get('/dashboard', 'DashboardController@index')->name('index'); Route::get('/dashboard/calls', 'DashboardController@calls'); Route::get('/dashboard/notes', 'DashboardController@notes'); Route::get('/dashboard/debts', 'DashboardController@debts'); Route::get('/dashboard/tasks', 'DashboardController@tasks'); Route::post('/dashboard/setTab', 'DashboardController@setTab'); });
There is one file that serves all route settings – app/Providers/RouteServiceProvider.php. It has two route files bound – web and API’s map() method:
public function map() { $this->mapApiRoutes(); $this->mapWebRoutes(); } protected function mapWebRoutes() { Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); } protected function mapApiRoutes() { Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); }
您是否注意到方法中提及的 middleware, namespace 和 prefix ? 这是您可以为整个文件设置全局配置的地方,因此不必为文件中的每个路由组重复这些设置。
它主要用于 API 路由,因为它们的设置通常是相同的,如下所示:
protected function mapApiRoutes(){ Route::group([ 'middleware' => ['api'], 'namespace' => $this->namespace, 'prefix' => 'api/v1', ], function ($router) { require base_path('routes/api.php'); });}
上述方法将在所有 API URLs 的开头加上 api/v1/ 前缀。
如果您有大量的路由,并且希望将它们分组到单独的文件中,那么您可以使用上一节中提到的相同文件 – app/Providers/RouteServiceProvider.php。如果您仔细查看它的 map() 方法,您将在末尾看到注释位置:
public function map(){ $this->mapApiRoutes(); $this->mapWebRoutes(); //}
如果愿意,您可以将其解释为添加更多文件的“邀请”。因此,您可以在此文件内创建另一个方法,例如 mapAdminRoutes(),然后将其添加到 map() 方法, 您的文件将被自动注册并加载。
但是,就我个人而言,我看不出这种方法有什么优势,而且我也没有经常看到这种做法。它会带来更多的路由分离,但有时您会迷失在那些文件中,不确定在哪里查找特定的路由。
说到更大的路由并迷失在那里,我们有一个 Artisan 命令可以帮助定位某个路由。
您可能知道 php artisan route:list 将展示项目中的所有路由
但您知道还有更多的过滤功能来找到您想要的东西吗? 只需添加带参数的 –method, 或 –name, 或 –path 。
通过 method 过滤 – GET, POST 等:
按名称或 URL 部分过滤:
这就是我所能告诉的关于在大型项目中分组路由的全部内容。你还有其他例子吗?请在评论中分享。
原文地址:https://laraveldaily.com/how-to-structure-routes-in-large-laravel-projects/
译文地址:https://learnku.com/laravel/t/38917
更多编程相关知识,请访问:编程视频!!
The above is the detailed content of Let’s talk about how to organize routing in large Laravel projects. For more information, please follow other related articles on the PHP Chinese website!