Laravel Routing
Basic Routing
use Illuminate\Support\Facades\Route;
Route::get('/greeting', function () {
return 'Hello World';
});
The Default Route Files
- Tất cả các route đã định nghĩa được tải tựu động qua
App\Providers\RouteServiceProvider
routes/web.php
định nghĩa các route cho web interface, các route này được lọc bởiweb middleware group
trong fileapp/Http/Kernel.php
và được bảo vệ bởi CSRFroute/api.php
định nghĩa các rote api và phụ thuộc vàoapi midddleware group
và URI prefix là/api
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
- VD route
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
Available Router Methods
- Laravel hỗ trợ 6 phương thức
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
- Đôi khi 1 route bạn có thể khai báo nhiều method như:
Route::match(['get', 'post'], '/', function () {
//
});
- Hoặc route có thể bất kỳ method nào
Route::any('/', function () {
//
});
- Chú ý: Khi định nghĩa nhiều route chung 1 URI thì các route get, post, put, patch, delete, and options phải được định nghĩa trước các route như: match, any hoặc redirect để đảm bảo request đến route chính xác.
Dependency Injection
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
// ...
});
CSRF Protection
- Mọi biểu mẫu HTML trỏ đến các tuyến POST, PUT, PATCH hoặc DELETE được xác định trong tệp route web phải bao gồm trường mã thông báo CSRF nếu không các reuqest sẽ bị từ chối
<form method="POST" action="/profile">
@csrf
...
</form>
Redirect Routes
- Bạn có thể dịnh nghĩa redirect route VD: /here -> /there
Route::redirect('/here', '/there');
- Route::redirect trả về mã trạng thái 302. Bạn có thể tùy chỉnh mã trạng thái bằng tham số thứ ba tùy chọn:
Route::redirect('/here', '/there', 301);
- Hoặc cũng có thể sử dụng method
permanentRedirect
để trả về status code 301:
Route::permanentRedirect('/here', '/there');
View Routes
- Nếu bạn cần định nghĩa route chỉ có view không cần thông qua Controller thì bạn có thể dùng method
view
:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
The Route List
- Để xem tất cả các route đã được định nghĩa thì có thể dùng command:
php artisan route:list
- Theo mặc định route middleware sẽ không hiển thị trong output, nếu bạn muốn hiển thị có thể thêm optional
-v
:
php artisan route:list -v
- Chỉ định URI cụ thể:
php artisan route:list --path=api
- Bỏ qua route của thư viện (third-party packages):
php artisan route:list --except-vendor
- Chỉ định hiển thị duy nhất route của third-party packages:
php artisan route:list --only-vendor
Route Parameters
Required Parameters
- Tên của tham số phải được dặt trong dấu
{}
, tên của tham số bao gồm: chữ, số, dấu_
Route::get('/user/{id}', function ($id) {
return 'User '.$id;
});
Route::get('/posts/{post}/comments/{comment}', function ($postId, $commentId) {
//
});
Parameters & Dependency Injection
use Illuminate\Http\Request;
Route::get('/user/{id}', function (Request $request, $id) {
return 'User '.$id;
});
Optional Parameters
Route::get('/user/{name?}', function ($name = null) {
return $name;
});
Route::get('/user/{name?}', function ($name = 'John') {
return $name;
});
Regular Expression Constraints
- Nếu request không khớp với ràng buộc route thì sẽ return 404
Route::get('/user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');
Route::get('/user/{id}', function ($id) {
//
})->where('id', '[0-9]+');
Route::get('/user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
- Có thể sử dụng các hàm mặc định:
Route::get('/user/{id}/{name}', function ($id, $name) {
//
})->whereNumber('id')->whereAlpha('name');
Route::get('/user/{name}', function ($name) {
//
})->whereAlphaNumeric('name');
Route::get('/user/{id}', function ($id) {
//
})->whereUuid('id');
Route::get('/user/{id}', function ($id) {
//
})->whereUlid('id');
Route::get('/category/{category}', function ($category) {
//
})->whereIn('category', ['movie', 'song', 'painting']);
Global Constraints
- Nếu muốn ràng buộc cho tất cả các route khi sử dụng cùng 1 tham số bạn cần thêm ràng buộc vào function
boot()
trongApp\Providers\RouteServiceProvider
:
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
Route::pattern('id', '[0-9]+');
}
- Khi đó các route dùng tham số id sẽ cần phải tuân thủ ràng buộc trên, vd:
Route::get('/user/{id}', function ($id) {
// Only executed if {id} is numeric...
});
Named Routes
- Tên của route là unique
- Chúng ta có thể đặt tên cho route:
Route::get('/user/profile', function () {
//
})->name('profile');
- Tên cho controller
Route::get(
'/user/profile',
[UserProfileController::class, 'show']
)->name('profile');
Generating URLs To Named Routes
- Khi đã định nghĩa tên route bạn có thể tạo URL, redirect theo tên route
// Generating URLs...
$url = route('profile');
// Generating Redirects...
return redirect()->route('profile');
return to_route('profile');
- Trong trường hợp sử dụng tham số:
Route::get('/user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1]);
Route::get('/user/{id}/profile', function ($id) {
//
})->name('profile');
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
// /user/1/profile?photos=yes
Inspecting The Current Route
- Kiểm tra request hiện tại có khớp với 1 tuyến đường đã được định nghĩa hay không thông qua tên của route có thể sử dụng, ví dụ bạn có thể check thông qua middleware:
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->route()->named('profile')) {
//
}
return $next($request);
}
Route Groups
- Bạn có thể nhóm các route theo middleware, Controller, domain
Middleware
Route::middleware(['first', 'second'])->group(function () {
Route::get('/', function () {
// Uses first & second middleware...
});
Route::get('/user/profile', function () {
// Uses first & second middleware...
});
});
Controllers
use App\Http\Controllers\OrderController;
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
Subdomain Routing
Route::domain('{account}.example.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
Route Prefixes
- Route prefix method được sử dụng để thêm tiền tố cho mỗi route trong nhóm các route
Route::prefix('admin')->group(function () {
Route::get('/users', function () {
// Matches The "/admin/users" URL
});
});
Route Name Prefixes
- Tương tự ta cũng có thể prefix theo name route
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
Route Model Binding
- Thông thường chúng ta hay truyền tham số ví dụ như id để lấy ra model tương ứng với id, thay vì truyền id ta có thể truyền 1 instance model tương ứng của id
- Nếu không có mô hình nào khớp với mô hình truyền vào thì mã lỗi 404 sẽ được trả về
Implicit Binding
use App\Http\Controllers\UserController;
use App\Models\User;
// Route definition...
Route::get('/users/{user}', [UserController::class, 'show']);
// Controller method definition...
public function show(User $user)
{
return view('user.profile', ['user' => $user]);
}
Soft Deleted Models
- Thông thường, liên kết mô hình tiềm ẩn sẽ không truy xuất các mô hình đã bị xóa mềm, tuy nhiên bạn có thể truy xuất mô hình đã bị xóa mềm bằng phương thức
withTrashed()
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();
Explicit Binding
Form Method Spoofing
- Html form không hỗ trỡ các method: PUT, PATCH, DELETE nên khi muốn sử dụng các method trên ta cần sử dụng như sau:
<form action="/example" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
- Có thể sử dụng Blade directive
<form action="/example" method="POST">
@method('PUT')
@csrf
</form>
Accessing The Current Route
- Check thông tin route hiện tại:
use Illuminate\Support\Facades\Route;
$route = Route::current(); // Illuminate\Routing\Route
$name = Route::currentRouteName(); // string
$action = Route::currentRouteAction(); // string
Rate Limiting
Defining Rate Limiters
- Bạn có thể giới hạn lưu lượng truy cập cho 1 route hoặc 1 nhóm route trong 1 phút
- Mặc định cấu hình
rate limiter configurations
được định nghĩa trongconfigureRateLimiting
method ở fileApp\Providers\RouteServiceProvider
Rate limiters
định nghĩa sử dụngRateLimiter
facade, thông quafor
method, for method chấp nhận mộtrate limiter name
và 1 closure trả về cấu hình limit được định nghĩa.
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
/**
* Configure the rate limiters for the application.
*/
protected function configureRateLimiting(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}
- Nếu request gửi đến vượt quá giới hạn chỉ định (số lượng request gửi đến/ 1 phút), Laravel sẽ tự động trả về HTTP status code 429, nếu bạn muốn custom mã lỗi trả về thì có thể dùng như sau:
RateLimiter::for('global', function (Request $request) {
return Limit::perMinute(1000)->response(function (Request $request, array $headers) {
return response('Custom response...', 429, $headers);
});
});
- Set limit request for route:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100);
});
Segmenting Rate Limits
- Đôi khi bạn chỉ muốn giới hạn request theo 1 điều kiện nhất định, ví dụ như giới hạn request trên 1 phút đối với 1 IP nhất định:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()->vipCustomer()
? Limit::none()
: Limit::perMinute(100)->by($request->ip());
});
- Hoặc là giới hạn cho từng ID người dùng hoặc IP như sau:
RateLimiter::for('uploads', function (Request $request) {
return $request->user()
? Limit::perMinute(100)->by($request->user()->id)
: Limit::perMinute(10)->by($request->ip());
});
Multiple Rate Limits
- Bạn cũng có thể giới hạn một mảng
rate limits
, mỗi limit sẽ được áp dụng cho route phụ thuộc vào thứ tự trong mảng
RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(500),
Limit::perMinute(3)->by($request->input('email')),
];
});
Attaching Rate Limiters To Routes
Rate limiters
có thể được gắn vào route hoặc nhóm route thông quathrottle middleware
:
Route::middleware(['throttle:uploads'])->group(function () {
Route::post('/audio', function () {
//
});
Route::post('/video', function () {
//
});
});
uploads
là tên củarate limiter
đã được định nghĩa- Default bạn có thể thấy Laravel sử dụng
rate limiter
có tên làapi
cho các routeapi
- Trong mảng thuộc tính
$middlewareGroups
:
protected $middlewareGroups = [
'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,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
- Và
rate limiter
có tênapi
đã được định nghĩa ở methodconfigureRateLimiting
trong fileapp/Providers/RouteServiceProvider.php
như sau:
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
- Tức là mặc định trong 1 phút đối với route của
api
thì 1 user hoặc 1 địa chỉ ip chỉ được gửi tối đa 60 request.
Cross-Origin Resource Sharing (CORS)
Route Caching
- Khi triển khai môi trường sản xuất nên sử dụng route cache để tăng performance
- Khi sử chạy command
artisan route:cache
thì sẽ sinh ra 1 filebootstrap/cache/routes-v7.php
, laravel thay vì đọc file trong folderroute
thì sẽ đọc file cache thay thế
php artisan route:cache
- Clear cache thì file
bootstrap/cache/routes-v7.php
sẽ bị xóa
php artisan route:clear
All rights reserved