Home > PHP Framework > Laravel > How does Laravel perform routing grouping? Sharing of 6 routing organization technologies

How does Laravel perform routing grouping? Sharing of 6 routing organization technologies

青灯夜游
Release: 2022-10-11 19:58:55
forward
2121 people have browsed it

How does Laravel perform routing grouping? Sharing of 6 routing organization technologies

Laravel routing is a feature that developers learn from the beginning. But as their project grew, it became increasingly difficult to manage the growing routing files, often requiring scrolling to find the correct Route::get() statement. Fortunately, there are some techniques to make route files shorter and more readable, let's look at different ways to group routes and their settings.

We won't just talk about the plain old Route::group(), that's beginner level. Let's dig a little deeper.


Group 1. Route::resource and Route::apiResource

Let’s start with the elephant in the room: this is probably the most commonly used grouping . If you have a typical set of CRUD operations around a model, you should group them into a Resource Controller

Such a controller contains up to 7 methods ( but probably less):

  • index()
  • create()
  • store()
  • show()
  • edit()
  • update()
  • destroy()

So if your route set corresponds to these methods, don't use:

Route::get('books', [BookController::class, 'index'])->name('books.index');
Route::get('books/create', [BookController::class, 'create'])->name('books.create');
Route::post('books', [BookController::class, 'store'])->name('books.store');
Route::get('books/{book}', [BookController::class, 'show'])->name('books.show');
Route::get('books/{book}/edit', [BookController::class, 'edit'])->name('books.edit');
Route::put('books/{book}', [BookController::class, 'update'])->name('books.update');
Route::delete('books/{book}', [BookController::class, 'destroy'])->name('books.destroy');
Copy after login

… You may only have one row:

Route::resource('books', BookController::class);
Copy after login

If you use an API project, you don't need a visual form for create/edit, so you can Covering 5 different syntaxes in 7 methods using apiResource():

Route::apiResource('books', BookController::class);
Copy after login

Also, I recommend you consider resource controllers even if you have 2- 4 methods instead of the full 7. Simply because it maintains standard naming conventions - for URLs, methods and route names. For example, in this case you don't need to provide the name manually:

Route::get('books/create', [BookController::class, 'create'])->name('books.create');
Route::post('books', [BookController::class, 'store'])->name('books.store');

// 相反,这里的名称“books.create”和“books.store”是自动分配的
Route::resource('books', BookController::class)->only(['create', 'store']);
Copy after login

Group 2. Nested sub-route group

Of course, everyone knows the general routing grouping. But for more complex projects, one level of grouping may not be enough.

Practical example: You want authorization routing to be grouped with the auth middleware, but internally you need to separate more subgroups, such as admins and simple users.

Route::middleware('auth')->group(function() {

    Route::middleware('is_admin')->prefix('admin')->group(function() {
     Route::get(...) // administrator routes
    });

    Route::middleware('is_user')->prefix('user')->group(function() {
     Route::get(...) // user routes
    });
});
Copy after login

Group 3. Group duplicate middleware

If you have a lot of middleware, have some in routing groups What to do if it happens repeatedly?

Route::prefix('students')->middleware(['auth', 'check.role', 'check.user.status', 'check.invoice.status', 'locale'])->group(function () {
    // ... 学生路由
});

Route::prefix('managers')->middleware(['auth', 'check.role', 'check.user.status', 'locale'])->group(function () {
    // ... 管理员路由
});
Copy after login

As you can see, there are 5 middlewares, 4 of which are duplicates. Therefore, in the app/Http/Kernel.php file, we can move these 4 to a separate middleware group:

protected $middlewareGroups = [
    // 此组是 Laravel 默认中间件组
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    // 此组是 Laravel 默认中间件组
    'api' => [
        // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    // 这是我们新的中间件组
    'check_user' => [
        'auth',
        'check.role',
        'check.user.status',
        'locale'
    ],
];
Copy after login

So we The middleware group name is check_user, now we can abbreviate the route:

Route::prefix('students')->middleware(['check_user', 'check.invoice.status'])->group(function () {
    // ... student routes
});

Route::prefix('managers')->middleware(['check_user'])->group(function () {
    // ... manager routes
});
Copy after login

Group 4. Same name controller, different namespace

It is very common, for example, to have HomeController set for different user roles, such as Admin/HomeController and User/HomeController. If you use the full path in routing, it looks like this:

Route::prefix('admin')->middleware('is_admin')->group(function () {
    Route::get('home', [\App\Http\Controllers\Admin\HomeController::class, 'index']);
});

Route::prefix('user')->middleware('is_user')->group(function () {
    Route::get('home', [\App\Http\Controllers\User\HomeController::class, 'index']);
});
Copy after login

The full path is used for each controller. This seems redundant, right? That's why many developers prefer to include only HomeController::class in the routes list and add something like this at the top:

use App\Http\Controllers\Admin\HomeController;
Copy after login

But here's the problem Yes we have the same controller class name! So, this doesn't work:

use App\Http\Controllers\Admin\HomeController;
use App\Http\Controllers\User\HomeController;
Copy after login

Which one is the controller of the "admin backend"? Well, one way is to change the name and assign an alias to one of them:

use App\Http\Controllers\Admin\HomeController as AdminHomeController;
use App\Http\Controllers\User\HomeController;

Route::prefix('admin')->middleware('is_admin')->group(function () {
    Route::get('home', [AdminHomeController::class, 'index']);
});

Route::prefix('user')->middleware('is_user')->group(function () {
    Route::get('home', [HomeController::class, 'index']);
});
Copy after login

But, personally, changing the name of the top class confuses me, I prefer the other One way: add a namespace () to the subfolder of the controller:

Route::prefix('admin')->namespace('App\Http\Controllers\Admin')->middleware('is_admin')->group(function () {
    Route::get('home', [HomeController::class, 'index']);
    // ... Admin 命名空间中的其他控制器
});

Route::prefix('user')->namespace('App\Http\Controllers\User')->middleware('is_user')->group(function () {
    Route::get('home', [HomeController::class, 'index']);
    // ... 来自用户命名空间的其他控制器
});
Copy after login

Group 5. Detach routing files

If you feel that routes/web.php or routes/api.php is too big, you can put some routes into a separate file, you can name it whatever you want , for example routes/admin.php.

To load this file, there are two methods: I call it the "Laravel method" and the "PHP method".

If you want to follow the structure of how Laravel builds its default route files, check out app/Providers/RouteServiceProvider.php:

public function boot()
{
    $this->configureRateLimiting();

    $this->routes(function () {
        Route::middleware('api')
            ->prefix('api')
            ->group(base_path('routes/api.php'));

        Route::middleware('web')
            ->group(base_path('routes/web.php'));
    });
}
Copy after login

routes/api.php and routes/web.php are both here, but with slightly different settings. So you just need to add the admin file here:

$this->routes(function () {
    Route::middleware('api')
        ->prefix('api')
        ->group(base_path('routes/api.php'));

    Route::middleware('web')
        ->group(base_path('routes/web.php'));

    Route::middleware('is_admin')
        ->group(base_path('routes/admin.php'));
});
Copy after login

如果你不想深入研究 服务提供者,还有一种更简单的方法 - 只需 include/require 您的路由文件到另一个文件中,就像你在 Laravel 框架之外的任何 PHP 文件。

事实上,这是由 Taylor Otwell 完成的,只需将 routes/auth.php 文件直接放入 Laravel Breeze 路由

routes/web.php:

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';
Copy after login

分组 6. Laravel 9 中的新功能: Route::controller ()

如果你的 Controller 中有一些方法,但它们不遵循标准的 Resource 结构,您仍然可以对它们进行分组,而无需为每个方法重复 Controller 名称。

取而代之的是:

Route::get('profile', [ProfileController::class, 'getProfile']);
Route::put('profile', [ProfileController::class, 'updateProfile']);
Route::delete('profile', [ProfileController::class, 'deleteProfile']);
Copy after login

您可以这样做:

Route::controller(ProfileController::class)->group(function() {
    Route::get('profile', 'getProfile');
    Route::put('profile', 'updateProfile');
    Route::delete('profile', 'deleteProfile');
});
Copy after login

此功能在 Laravel 9 和 Laravel 8 的最新小版本中可用。


就是这样,这些分组技术有望帮助你组织和维护的路由,无论你的项目发展到多大。

原文地址:https://laravel-news.com/laravel-route-organization-tips

译文地址:https://learnku.com/laravel/t/68476

【相关推荐:laravel视频教程

The above is the detailed content of How does Laravel perform routing grouping? Sharing of 6 routing organization technologies. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:learnku.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template