1. Routing
// routes/web.php
use App\Http\Controllers\ProductController;
Route::get('/', fn () => view('welcome'));
// Route parameters
Route::get('/products/{product}', [ProductController::class, 'show']);
Route::get('/categories/{category}/products', [ProductController::class, 'byCategory']);
// Optional parameters
Route::get('/search/{query?}', [ProductController::class, 'search']);
// Named routes
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
// Route groups
Route::prefix('api/v1')->middleware('auth:sanctum')->group(function () {
Route::apiResource('products', ProductController::class);
Route::apiResource('orders', OrderController::class);
});
2. Controllers
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index()
{
$products = Product::with('category')
->where('is_active', true)
->paginate(20);
return view('products.index', compact('products'));
}
public function show(Product $product) // Route model binding
{
return view('products.show', compact('product'));
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'price' => 'required|numeric|min:0',
]);
$product = Product::create($validated);
return redirect()->route('products.show', $product);
}
}
3. Resource Controller
php artisan make:controller ProductController --resource --model=Product
// index, create, store, show, edit, update, destroy
Route::resource('products', ProductController::class);
// API only (no create, edit)
Route::apiResource('products', ProductController::class);
4. Middleware
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureIsAdmin
{
public function handle(Request $request, Closure $next)
{
if ($request->user()?->role !== 'admin') {
abort(403, 'Unauthorized');
}
return $next($request);
}
}
// bootstrap/app.php (Laravel 11)
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'admin' => EnsureIsAdmin::class,
]);
})
// Sử dụng
Route::middleware('admin')->group(function () {
Route::get('/admin/dashboard', ...);
});
5. Rate Limiting
// bootstrap/app.php
use Illuminate\Cache\RateLimiting\Limit;
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
Bài tiếp theo: Blade Templates & Frontend.