Trong khuôn khổ của Laravel, các route của api được tách thành một file duy nhất, đó là file api.php nằm trong thư mục routes. Nếu chúng ta muốn thêm version vào route api thì chúng ta sẽ làm như sau:
Route::prefix('v1')->namespace('Api\V1')->group(function() {
Route::resource('photos', 'PhotoController');
});
Route::prefix('v2')->namespace('Api\V2')->group(function() {
Route::resource('photos', 'PhotoController');
});
Nhìn cách giải quyết trên thì không có vấn đề gì khi bạn dùng cho dự án nhỏ (không có quá nhiều route). Nhưng đối với các dự án lớn (có rất nhiều route) thì chúng ta sẽ phát hiện ra rằng khi có nhiều route và nhiều version nữa thì file api.php sẽ quá lớn để chúng ta quản lý.
Để giải quyết tình trạng trên chúng ta sẽ chia các version api thành các file khác nhau tương ứng với version đó.
Đầu tiên, chúng ta sẽ thực hiện thêm các function như mapApiVersionRoutes, getApiVersion, getApiNamespace vào file app\Providers\RouteServiceProvider.php để xác định các file version api. Sau khi chỉnh sửa nội dung file sẽ trông giống như sau:
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
...
protected $namespace = 'App\\Http\\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
...
$this->mapApiVersionRoutes();
}
...
protected function mapApiVersionRoutes()
{
$files = \File::allFiles(base_path('routes'));
foreach ($files as $key => $file) {
$basename = pathinfo($file)['basename'];
if (preg_match("/api_v[0-9].php/", $basename)) {
Route::prefix("api/v{$this->getApiVersion($basename)}")
->middleware('api')
->namespace($this->getApiNamespace($this->getApiVersion($basename)))
->group(base_path("routes/{$basename}"));
}
}
}
private function getApiVersion($basename)
{
return str_replace(["api_v", ".php"], "", $basename);
}
private function getApiNamespace($version)
{
if ($this->namespace) {
return "{$this->namespace}\Api\V{$version}";
}
return "";
}
}
Như vậy thôi, chúng ta đã setting xong chức năng auto map version api rồi, để hệ thống có thể tự động map api route được, chúng ta cần đặt tên file api theo format như sau:
Format: api_v{version}.php
Ví dụ: api_v1.php, api_v2.php,...
Để kiểm tra xem hệ thống map version api của chúng ta có hoạt động được hay không, đầu tiên chúng ta cần tạo ra hai controller để thử nghiệm bằng lệnh command sau:
php artisan make:controller Api\V1\PhotoController --resource
php artisan make:controller Api\V2\PhotoController --resource
Tiếp theo đó, chúng ta cần hai file route trong thư mục routes và có nội dung như sau:
routes\api_v1.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API V1 Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::resource('photos', PhotoController::class);
routes\api_v2.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API V2 Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::resource('photos', PhotoController::class);
Cuối cùng, chúng ta chạy lệnh command sau để xem các route api đã chia thành các version hay chưa:
php artisan roue:list
Kết quả:
Tôi hy vọng bạn thích hướng dẫn này. Nếu bạn có bất kỳ câu hỏi nào hãy liên hệ với chúng tôi qua trang contact. Cảm ơn bạn.