라우팅
- 기본 라우팅
- 라우트 매개변수
- 이름 있는 라우트
- 라우트 그룹
- 라우트 모델 바인딩
- 대체 라우트
- 속도 제한
- 폼 메소드 스푸핑
- 현재 라우트 접근
- CORS(Cross-Origin Resource Sharing)
- 라우트 캐싱
기본 라우팅
가장 기본적인 Laravel 라우트는 URI와 클로저를 받아들이며, 복잡한 라우팅 설정 파일 없이 라우트와 동작을 정의하는 매우 간단하고 표현적인 방법을 제공합니다.
use Illuminate\Support\Facades\Route; Route::get('/greeting', function () { return 'Hello World';});
기본 라우트 파일
모든 Laravel 라우트는 routes 디렉토리에 있는 라우트 파일에 정의됩니다. 이러한 파일은 애플리케이션의 bootstrap/app.php 파일에 지정된 구성을 사용하여 Laravel에 의해 자동으로 로드됩니다. routes/web.php 파일은 웹 인터페이스용 라우트를 정의합니다. 이러한 라우트는 세션 상태 및 CSRF 보호와 같은 기능을 제공하는 web 미들웨어 그룹에 할당됩니다.
대부분의 애플리케이션에서는 routes/web.php 파일에서 라우트를 정의하는 것으로 시작합니다. routes/web.php에 정의된 라우트는 브라우저에서 정의된 라우트의 URL을 입력하여 액세스할 수 있습니다. 예를 들어, 브라우저에서 http://example.com/user로 이동하여 다음 라우트에 액세스할 수 있습니다.
use App\Http\Controllers\UserController; Route::get('/user', [UserController::class, 'index']);
API 라우트
애플리케이션이 상태 비저장 API를 제공할 경우 install:api Artisan 명령을 사용하여 API 라우팅을 활성화할 수 있습니다.
php artisan install:api
install:api 명령은 Laravel Sanctum을 설치합니다. Sanctum은 타사 API 소비자, SPA 또는 모바일 애플리케이션을 인증하는 데 사용할 수 있는 강력하면서도 간단한 API 토큰 인증 가드를 제공합니다. 또한 install:api 명령은 routes/api.php 파일을 생성합니다.
Route::get('/user', function (Request $request) { return $request->user();})->middleware('auth:sanctum');
routes/api.php의 경로는 상태가 없으며 api 미들웨어 그룹에 할당됩니다. 또한 /api URI 접두사가 이러한 경로에 자동으로 적용되므로 파일의 모든 경로에 수동으로 적용할 필요가 없습니다. 애플리케이션의 bootstrap/app.php 파일을 수정하여 접두사를 변경할 수 있습니다.
->withRouting( api: __DIR__.'/../routes/api.php', apiPrefix: 'api/admin', // ...)
사용 가능한 라우터 메서드
라우터에서는 모든 HTTP 동사에 응답하는 경로를 등록할 수 있습니다.
Route::get($uri, $callback);Route::post($uri, $callback);Route::put($uri, $callback);Route::patch($uri, $callback);Route::delete($uri, $callback);Route::options($uri, $callback);
때로는 여러 HTTP 동사에 응답하는 경로를 등록해야 할 수도 있습니다. match 메서드를 사용하여 그렇게 할 수 있습니다. 또는 any 메서드를 사용하여 모든 HTTP 동사에 응답하는 경로를 등록할 수도 있습니다.
Route::match(['get', 'post'], '/', function () { // ...}); Route::any('/', function () { // ...});
동일한 URI를 공유하는 여러 경로를 정의할 때 get, post, put, patch, delete 및 options 메서드를 사용하는 경로는 any, match 및 redirect 메서드를 사용하는 경로보다 먼저 정의해야 합니다. 이렇게 하면 들어오는 요청이 올바른 경로와 일치하도록 할 수 있습니다.
의존성 주입
경로 콜백 시그니처에서 경로에 필요한 모든 종속성을 타입 힌트로 지정할 수 있습니다. 선언된 종속성은 Laravel 서비스 컨테이너에 의해 자동으로 확인되어 콜백에 주입됩니다. 예를 들어 Illuminate\Http\Request 클래스를 타입 힌트로 지정하여 현재 HTTP 요청을 경로 콜백에 자동으로 주입할 수 있습니다.
use Illuminate\Http\Request; Route::get('/users', function (Request $request) { // ...});
CSRF 보호
web 경로 파일에 정의된 POST, PUT, PATCH 또는 DELETE 경로를 가리키는 모든 HTML 양식에는 CSRF 토큰 필드가 포함되어야 합니다. 그렇지 않으면 요청이 거부됩니다. CSRF 보호에 대한 자세한 내용은 CSRF 문서에서 확인할 수 있습니다.
<form method="POST" action="/profile"> @csrf ...</form>
리디렉션 경로
다른 URI로 리디렉션하는 경로를 정의하는 경우 Route::redirect 메서드를 사용할 수 있습니다. 이 메서드는 간단한 리디렉션을 수행하기 위해 전체 경로 또는 컨트롤러를 정의할 필요가 없도록 편리한 바로 가기를 제공합니다.
Route::redirect('/here', '/there');
기본적으로 Route::redirect는 302 상태 코드를 반환합니다. 선택적 세 번째 매개변수를 사용하여 상태 코드를 사용자 지정할 수 있습니다.
Route::redirect('/here', '/there', 301);
또는 Route::permanentRedirect 메서드를 사용하여 301 상태 코드를 반환할 수 있습니다.
Route::permanentRedirect('/here', '/there');
리디렉션 경로에서 경로 매개변수를 사용할 때 다음 매개변수는 Laravel에서 예약되어 있으며 사용할 수 없습니다. destination 및 status.
뷰 경로
경로에서 뷰만 반환해야 하는 경우 Route::view 메서드를 사용할 수 있습니다. redirect 메서드와 마찬가지로 이 메서드는 전체 경로 또는 컨트롤러를 정의할 필요가 없도록 간단한 바로 가기를 제공합니다. view 메서드는 URI를 첫 번째 인수로, 뷰 이름을 두 번째 인수로 받습니다. 또한 뷰에 전달할 데이터 배열을 선택적 세 번째 인수로 제공할 수 있습니다.
Route::view('/welcome', 'welcome'); Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
뷰 경로에서 경로 매개변수를 사용할 때 다음 매개변수는 Laravel에서 예약되어 있으며 사용할 수 없습니다. view, data, status 및 headers.
경로 나열
route:list Artisan 명령을 사용하면 애플리케이션에서 정의된 모든 경로에 대한 개요를 쉽게 제공할 수 있습니다.
php artisan route:list
기본적으로 각 라우트에 할당된 라우트 미들웨어는 route:list 출력에 표시되지 않습니다. 그러나 명령어에 -v 옵션을 추가하여 라라벨이 라우트 미들웨어 및 미들웨어 그룹 이름을 표시하도록 지시할 수 있습니다.
php artisan route:list -v # 미들웨어 그룹 확장...php artisan route:list -vv
또한 라라벨에게 주어진 URI로 시작하는 라우트만 표시하도록 지시할 수도 있습니다.
php artisan route:list --path=api
또한 route:list 명령어를 실행할 때 --except-vendor 옵션을 제공하여 타사 패키지에 의해 정의된 모든 라우트를 숨기도록 라라벨에 지시할 수 있습니다.
php artisan route:list --except-vendor
마찬가지로 route:list 명령어를 실행할 때 --only-vendor 옵션을 제공하여 타사 패키지에 의해 정의된 라우트만 표시하도록 라라벨에 지시할 수도 있습니다.
php artisan route:list --only-vendor
라우팅 사용자 정의
기본적으로 애플리케이션의 라우트는 bootstrap/app.php 파일에 의해 구성되고 로드됩니다.
<?php use Illuminate\Foundation\Application; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', )->create();
그러나 때로는 애플리케이션 라우트의 하위 집합을 포함하는 완전히 새로운 파일을 정의하고 싶을 수도 있습니다. 이를 위해 withRouting 메서드에 then 클로저를 제공할 수 있습니다. 이 클로저 내에서 애플리케이션에 필요한 추가 라우트를 등록할 수 있습니다.
use Illuminate\Support\Facades\Route; ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', then: function () { Route::middleware('api') ->prefix('webhooks') ->name('webhooks.') ->group(base_path('routes/webhooks.php')); },)
또는 withRouting 메서드에 using 클로저를 제공하여 라우트 등록을 완전히 제어할 수도 있습니다. 이 인수가 전달되면 프레임워크에서 HTTP 라우트가 등록되지 않으며 모든 라우트를 수동으로 등록해야 합니다.
use Illuminate\Support\Facades\Route; ->withRouting( commands: __DIR__.'/../routes/console.php', using: function () { Route::middleware('api') ->prefix('api') ->group(base_path('routes/api.php')); Route::middleware('web') ->group(base_path('routes/web.php')); },)
라우트 매개변수
필수 매개변수
경로 내에서 URI의 세그먼트를 캡처해야 할 때가 있습니다. 예를 들어, URL에서 사용자의 ID를 캡처해야 할 수 있습니다. 경로 매개변수를 정의하여 이를 수행할 수 있습니다.
Route::get('/user/{id}', function (string $id) { return 'User '.$id;});
경로에 필요한 만큼 많은 경로 매개변수를 정의할 수 있습니다.
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) { // ...});
경로 매개변수는 항상 {} 중괄호로 묶여 있으며, 영문자로 구성되어야 합니다. 밑줄 (_)도 경로 매개변수 이름에서 허용됩니다. 경로 매개변수는 순서에 따라 경로 콜백/컨트롤러에 주입됩니다. 경로 콜백/컨트롤러 인수의 이름은 중요하지 않습니다.
매개변수와 의존성 주입
경로에 Laravel 서비스 컨테이너가 경로의 콜백에 자동으로 주입하기를 원하는 종속성이 있는 경우, 종속성 다음에 경로 매개변수를 나열해야 합니다.
use Illuminate\Http\Request; Route::get('/user/{id}', function (Request $request, string $id) { return 'User '.$id;});
선택적 매개변수
URI에 항상 존재하지 않을 수 있는 경로 매개변수를 지정해야 할 때가 있습니다. 매개변수 이름 뒤에 ? 표시를 추가하여 이를 수행할 수 있습니다. 경로의 해당 변수에 기본값을 지정해야 합니다.
Route::get('/user/{name?}', function (?string $name = null) { return $name;}); Route::get('/user/{name?}', function (?string $name = 'John') { return $name;});
정규식 제약 조건
경로 인스턴스에서 where 메서드를 사용하여 경로 매개변수의 형식을 제약할 수 있습니다. where 메서드는 매개변수의 이름과 매개변수가 제약되는 방식을 정의하는 정규식을 허용합니다.
Route::get('/user/{name}', function (string $name) { // ...})->where('name', '[A-Za-z]+'); Route::get('/user/{id}', function (string $id) { // ...})->where('id', '[0-9]+'); Route::get('/user/{id}/{name}', function (string $id, string $name) { // ...})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
편의를 위해 자주 사용되는 일부 정규식 패턴에는 경로에 패턴 제약 조건을 빠르게 추가할 수 있는 헬퍼 메서드가 있습니다.
Route::get('/user/{id}/{name}', function (string $id, string $name) { // ...})->whereNumber('id')->whereAlpha('name'); Route::get('/user/{name}', function (string $name) { // ...})->whereAlphaNumeric('name'); Route::get('/user/{id}', function (string $id) { // ...})->whereUuid('id'); Route::get('/user/{id}', function (string $id) { // ...})->whereUlid('id'); Route::get('/category/{category}', function (string $category) { // ...})->whereIn('category', ['movie', 'song', 'painting']); Route::get('/category/{category}', function (string $category) { // ...})->whereIn('category', CategoryEnum::cases());
들어오는 요청이 경로 패턴 제약 조건과 일치하지 않으면 404 HTTP 응답이 반환됩니다.
전역 제약 조건
경로 매개변수가 항상 주어진 정규식으로 제약되도록 하려면 pattern 메서드를 사용할 수 있습니다. 이러한 패턴은 애플리케이션의 App\Providers\AppServiceProvider 클래스의 boot 메서드에서 정의해야 합니다.
use Illuminate\Support\Facades\Route; /** * Bootstrap any application services. */public function boot(): void{ Route::pattern('id', '[0-9]+');}
패턴이 정의되면 해당 매개변수 이름을 사용하는 모든 경로에 자동으로 적용됩니다.
Route::get('/user/{id}', function (string $id) { // {id}가 숫자일 경우에만 실행됩니다...});
인코딩된 슬래시
Laravel 라우팅 구성 요소는 /를 제외한 모든 문자가 경로 매개변수 값 내에 존재하도록 허용합니다. where 조건 정규식을 사용하여 /가 자리 표시자의 일부가 되도록 명시적으로 허용해야 합니다.
Route::get('/search/{search}', function (string $search) { return $search;})->where('search', '.*');
인코딩된 슬래시는 마지막 경로 세그먼트 내에서만 지원됩니다.
이름있는 라우트
이름있는 라우트를 사용하면 특정 경로에 대한 URL 또는 리디렉션을 편리하게 생성할 수 있습니다. 경로 정의에 name 메서드를 연결하여 경로 이름을 지정할 수 있습니다.
Route::get('/user/profile', function () { // ...})->name('profile');
컨트롤러 액션에 대한 경로 이름을 지정할 수도 있습니다.
Route::get( '/user/profile', [UserProfileController::class, 'show'])->name('profile');
경로 이름은 항상 고유해야 합니다.
이름있는 라우트에 대한 URL 생성
지정된 경로에 이름을 할당한 후에는 Laravel의 route 및 redirect 헬퍼 함수를 통해 URL 또는 리디렉션을 생성할 때 경로 이름을 사용할 수 있습니다.
// URL 생성...$url = route('profile'); // 리디렉션 생성...return redirect()->route('profile'); return to_route('profile');
이름있는 경로가 매개변수를 정의하는 경우, route 함수에 두 번째 인수로 매개변수를 전달할 수 있습니다. 주어진 매개변수는 생성된 URL의 올바른 위치에 자동으로 삽입됩니다.
Route::get('/user/{id}/profile', function (string $id) { // ...})->name('profile'); $url = route('profile', ['id' => 1]);
배열에 추가 매개변수를 전달하면 해당 키/값 쌍이 생성된 URL의 쿼리 문자열에 자동으로 추가됩니다.
Route::get('/user/{id}/profile', function (string $id) { // ...})->name('profile'); $url = route('profile', ['id' => 1, 'photos' => 'yes']); // /user/1/profile?photos=yes
때로는 현재 로케일과 같이 URL 매개변수에 대한 요청 범위 기본값을 지정하는 것이 좋습니다. 이를 위해 URL::defaults 메서드를 사용할 수 있습니다.
현재 경로 검사
현재 요청이 지정된 이름있는 경로로 라우팅되었는지 확인하려면 Route 인스턴스에서 named 메서드를 사용할 수 있습니다. 예를 들어, 경로 미들웨어에서 현재 경로 이름을 확인할 수 있습니다.
use Closure;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response; /** * 들어오는 요청을 처리합니다. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */public function handle(Request $request, Closure $next): Response{ if ($request->route()->named('profile')) { // ... } return $next($request);}
라우트 그룹
라우트 그룹을 사용하면 각 개별 라우트에 해당 속성을 정의할 필요 없이 미들웨어와 같은 라우트 속성을 많은 라우트에서 공유할 수 있습니다.
중첩된 그룹은 속성을 해당 상위 그룹과 지능적으로 "병합"하려고 시도합니다. 미들웨어와 where 조건은 병합되는 반면, 이름과 접두사는 추가됩니다. 네임스페이스 구분 기호와 URI 접두사의 슬래시는 적절한 위치에 자동으로 추가됩니다.
미들웨어
그룹 내의 모든 경로에 미들웨어를 할당하려면 그룹을 정의하기 전에 middleware 메서드를 사용할 수 있습니다. 미들웨어는 배열에 나열된 순서대로 실행됩니다.
Route::middleware(['first', 'second'])->group(function () { Route::get('/', function () { // 첫 번째 및 두 번째 미들웨어 사용... }); Route::get('/user/profile', function () { // 첫 번째 및 두 번째 미들웨어 사용... });});
컨트롤러
경로 그룹이 모두 동일한 컨트롤러를 사용하는 경우, controller 메서드를 사용하여 그룹 내의 모든 경로에 대한 공통 컨트롤러를 정의할 수 있습니다. 그런 다음, 경로를 정의할 때 호출하는 컨트롤러 메서드만 제공하면 됩니다.
use App\Http\Controllers\OrderController; Route::controller(OrderController::class)->group(function () { Route::get('/orders/{id}', 'show'); Route::post('/orders', 'store');});
서브도메인 라우팅
라우트 그룹은 서브도메인 라우팅을 처리하는 데에도 사용할 수 있습니다. 서브도메인은 경로 URI와 마찬가지로 경로 매개변수를 할당할 수 있으므로 경로 또는 컨트롤러에서 사용할 서브도메인의 일부를 캡처할 수 있습니다. 서브도메인은 그룹을 정의하기 전에 domain 메서드를 호출하여 지정할 수 있습니다.
Route::domain('{account}.example.com')->group(function () { Route::get('/user/{id}', function (string $account, string $id) { // ... });});
서브도메인 경로에 도달할 수 있는지 확인하려면 루트 도메인 경로를 등록하기 전에 서브도메인 경로를 등록해야 합니다. 이렇게 하면 URI 경로가 동일한 서브도메인 경로를 루트 도메인 경로가 덮어쓰는 것을 방지할 수 있습니다.
경로 접두사
prefix 메서드를 사용하여 그룹의 각 경로에 지정된 URI를 접두사로 지정할 수 있습니다. 예를 들어, 그룹 내의 모든 경로 URI에 admin을 접두사로 지정할 수 있습니다.
Route::prefix('admin')->group(function () { Route::get('/users', function () { // "/admin/users" URL과 일치합니다. });});
경로 이름 접두사
name 메서드를 사용하여 그룹의 각 경로 이름에 지정된 문자열을 접두사로 지정할 수 있습니다. 예를 들어, 그룹의 모든 경로 이름에 admin을 접두사로 지정할 수 있습니다. 지정된 문자열은 지정된 대로 정확하게 경로 이름에 접두사로 지정되므로 접두사에 후행 . 문자를 제공해야 합니다.
Route::name('admin.')->group(function () { Route::get('/users', function () { // "admin.users" 이름이 할당된 경로... })->name('users');});
라우트 모델 바인딩
모델 ID를 경로 또는 컨트롤러 액션에 주입할 때, 해당 ID에 해당하는 모델을 검색하기 위해 데이터베이스를 쿼리하는 경우가 많습니다. Laravel 라우트 모델 바인딩은 모델 인스턴스를 경로에 직접 자동으로 주입하는 편리한 방법을 제공합니다. 예를 들어, 사용자의 ID를 주입하는 대신, 주어진 ID와 일치하는 전체 User 모델 인스턴스를 주입할 수 있습니다.
암시적 바인딩
Laravel은 타입 힌트된 변수 이름이 경로 세그먼트 이름과 일치하는 경로 또는 컨트롤러 액션에서 정의된 Eloquent 모델을 자동으로 확인합니다. 예를 들면 다음과 같습니다.
use App\Models\User; Route::get('/users/{user}', function (User $user) { return $user->email;});
$user 변수는 App\Models\User Eloquent 모델로 타입 힌트되고 변수 이름이 {user} URI 세그먼트와 일치하므로, Laravel은 요청 URI의 해당 값과 일치하는 ID를 가진 모델 인스턴스를 자동으로 주입합니다. 데이터베이스에서 일치하는 모델 인스턴스를 찾을 수 없으면 404 HTTP 응답이 자동으로 생성됩니다.
물론 컨트롤러 메서드를 사용할 때도 암시적 바인딩이 가능합니다. 다시 한번, {user} URI 세그먼트가 App\Models\User 타입 힌트를 포함하는 컨트롤러의 $user 변수와 일치하는지 확인하십시오.
use App\Http\Controllers\UserController;use App\Models\User; // 경로 정의...Route::get('/users/{user}', [UserController::class, 'show']); // 컨트롤러 메서드 정의...public function show(User $user){ return view('user.profile', ['user' => $user]);}
소프트 삭제된 모델
일반적으로 암시적 모델 바인딩은 소프트 삭제된 모델을 검색하지 않습니다. 그러나 경로의 정의에 withTrashed 메서드를 연결하여 암시적 바인딩이 이러한 모델을 검색하도록 지시할 수 있습니다.
use App\Models\User; Route::get('/users/{user}', function (User $user) { return $user->email;})->withTrashed();
키 사용자 지정
id 이외의 열을 사용하여 Eloquent 모델을 확인해야 할 때가 있습니다. 이렇게 하려면 경로 매개변수 정의에서 열을 지정할 수 있습니다.
use App\Models\Post; Route::get('/posts/{post:slug}', function (Post $post) { return $post;});
모델 바인딩이 주어진 모델 클래스를 검색할 때 항상 id 이외의 데이터베이스 열을 사용하도록 하려면 Eloquent 모델에서 getRouteKeyName 메서드를 재정의할 수 있습니다.
/** * 모델의 경로 키를 가져옵니다. */public function getRouteKeyName(): string{ return 'slug';}
사용자 지정 키 및 범위 지정
단일 경로 정의에서 여러 Eloquent 모델을 암시적으로 바인딩할 때, 두 번째 Eloquent 모델이 이전 Eloquent 모델의 자식이어야 하도록 범위를 지정할 수 있습니다. 예를 들어, 특정 사용자에 대한 슬러그로 블로그 게시물을 검색하는 이 경로 정의를 고려하십시오.
use App\Models\Post;use App\Models\User; Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post;});
중첩된 경로 매개변수로 사용자 지정 키 지정 암시적 바인딩을 사용하는 경우, Laravel은 상위의 관계 이름을 추측하기 위한 규칙을 사용하여 상위 모델을 기준으로 중첩된 모델을 검색하도록 쿼리 범위를 자동으로 지정합니다. 이 경우, User 모델에 Post 모델을 검색하는 데 사용할 수 있는 posts(경로 매개변수 이름의 복수형)라는 관계가 있다고 가정합니다.
원하는 경우, 사용자 지정 키가 제공되지 않은 경우에도 Laravel이 "자식" 바인딩의 범위를 지정하도록 지시할 수 있습니다. 이렇게 하려면 경로를 정의할 때 scopeBindings 메서드를 호출하면 됩니다.
use App\Models\Post;use App\Models\User; Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post;})->scopeBindings();
또는, 전체 경로 정의 그룹에서 범위 지정 바인딩을 사용하도록 지시할 수 있습니다.
Route::scopeBindings()->group(function () { Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) { return $post; });});
마찬가지로, withoutScopedBindings 메서드를 호출하여 Laravel이 바인딩의 범위를 지정하지 않도록 명시적으로 지시할 수 있습니다.
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post;})->withoutScopedBindings();
누락된 모델 동작 사용자 지정
일반적으로 암시적으로 바인딩된 모델을 찾을 수 없으면 404 HTTP 응답이 생성됩니다. 그러나 경로를 정의할 때 missing 메서드를 호출하여 이 동작을 사용자 지정할 수 있습니다. missing 메서드는 암시적으로 바인딩된 모델을 찾을 수 없는 경우 호출되는 클로저를 허용합니다.
use App\Http\Controllers\LocationsController;use Illuminate\Http\Request;use Illuminate\Support\Facades\Redirect; Route::get('/locations/{location:slug}', [LocationsController::class, 'show']) ->name('locations.view') ->missing(function (Request $request) { return Redirect::route('locations.index'); });
암시적 Enum 바인딩
PHP 8.1은 Enum에 대한 지원을 도입했습니다. 이 기능을 보완하기 위해 Laravel을 사용하면 경로 정의에서 backed Enum을 타입 힌트로 지정할 수 있으며, Laravel은 해당 경로 세그먼트가 유효한 Enum 값에 해당하는 경우에만 경로를 호출합니다. 그렇지 않으면 404 HTTP 응답이 자동으로 반환됩니다. 예를 들어, 다음 Enum이 주어지면 다음과 같습니다.
<?php namespace App\Enums; enum Category: string{ case Fruits = 'fruits'; case People = 'people';}
{category} 라우트 세그먼트가 fruits 또는 people인 경우에만 호출되는 라우트를 정의할 수 있습니다. 그렇지 않으면 Laravel은 404 HTTP 응답을 반환합니다.
use App\Enums\Category;use Illuminate\Support\Facades\Route; Route::get('/categories/{category}', function (Category $category) { return $category->value;});
명시적 바인딩
모델 바인딩을 사용하기 위해 라라벨의 암시적, 규칙 기반 모델 확인을 사용할 필요는 없습니다. 라우트 매개변수가 모델에 어떻게 대응하는지 명시적으로 정의할 수도 있습니다. 명시적 바인딩을 등록하려면 라우터의 model 메서드를 사용하여 주어진 매개변수에 대한 클래스를 지정하십시오. AppServiceProvider 클래스의 boot 메서드 시작 부분에 명시적 모델 바인딩을 정의해야 합니다:
use App\Models\User;use Illuminate\Support\Facades\Route; /** * 모든 애플리케이션 서비스 부트스트랩. */public function boot(): void{ Route::model('user', User::class);}
다음으로, {user} 매개변수를 포함하는 라우트를 정의합니다:
use App\Models\User; Route::get('/users/{user}', function (User $user) { // ...});
모든 {user} 매개변수를 App\Models\User 모델에 바인딩했으므로 해당 클래스의 인스턴스가 라우트에 주입됩니다. 예를 들어, users/1에 대한 요청은 ID가 1인 데이터베이스의 User 인스턴스를 주입합니다.
데이터베이스에서 일치하는 모델 인스턴스를 찾을 수 없으면 404 HTTP 응답이 자동으로 생성됩니다.
확인 로직 사용자 정의
자신만의 모델 바인딩 확인 로직을 정의하려는 경우 Route::bind 메서드를 사용할 수 있습니다. bind 메서드에 전달하는 클로저는 URI 세그먼트의 값을 받고 라우트에 주입해야 하는 클래스의 인스턴스를 반환해야 합니다. 다시 말하지만, 이러한 사용자 정의는 애플리케이션의 AppServiceProvider의 boot 메서드에서 이루어져야 합니다:
use App\Models\User;use Illuminate\Support\Facades\Route; /** * 모든 애플리케이션 서비스 부트스트랩. */public function boot(): void{ Route::bind('user', function (string $value) { return User::where('name', $value)->firstOrFail(); });}
또는 Eloquent 모델에서 resolveRouteBinding 메서드를 재정의할 수 있습니다. 이 메서드는 URI 세그먼트의 값을 받고 라우트에 주입해야 하는 클래스의 인스턴스를 반환해야 합니다:
/** * 바인딩된 값에 대한 모델을 검색합니다. * * @param mixed $value * @param string|null $field * @return \Illuminate\Database\Eloquent\Model|null */public function resolveRouteBinding($value, $field = null){ return $this->where('name', $value)->firstOrFail();}
라우트가 암시적 바인딩 스코핑을 사용하는 경우, 부모 모델의 자식 바인딩을 확인하기 위해 resolveChildRouteBinding 메서드가 사용됩니다:
/** * 바인딩된 값에 대한 자식 모델을 검색합니다. * * @param string $childType * @param mixed $value * @param string|null $field * @return \Illuminate\Database\Eloquent\Model|null */public function resolveChildRouteBinding($childType, $value, $field){ return parent::resolveChildRouteBinding($childType, $value, $field);}
폴백 라우트
Route::fallback 메서드를 사용하여 들어오는 요청과 일치하는 다른 라우트가 없을 때 실행될 라우트를 정의할 수 있습니다. 일반적으로 처리되지 않은 요청은 애플리케이션의 예외 처리기를 통해 자동으로 "404" 페이지를 렌더링합니다. 그러나 일반적으로 routes/web.php 파일 내에서 fallback 라우트를 정의하므로 web 미들웨어 그룹의 모든 미들웨어가 라우트에 적용됩니다. 필요에 따라 이 라우트에 추가 미들웨어를 자유롭게 추가할 수 있습니다:
Route::fallback(function () { // ...});
속도 제한
속도 제한기 정의
라라벨에는 주어진 라우트 또는 라우트 그룹에 대한 트래픽 양을 제한하는 데 사용할 수 있는 강력하고 사용자 정의 가능한 속도 제한 서비스가 포함되어 있습니다. 시작하려면 애플리케이션의 요구 사항을 충족하는 속도 제한기 구성을 정의해야 합니다.
속도 제한기는 애플리케이션의 App\Providers\AppServiceProvider 클래스의 boot 메서드 내에서 정의할 수 있습니다:
use Illuminate\Cache\RateLimiting\Limit;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter; /** * 모든 애플리케이션 서비스를 부트스트랩합니다. */protected function boot(): void{ RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); });}
속도 제한기는 RateLimiter 파사드의 for 메서드를 사용하여 정의됩니다. for 메서드는 속도 제한기 이름과, 속도 제한기에 할당된 라우트에 적용되어야 하는 제한 구성을 반환하는 클로저를 받습니다. 제한 구성은 Illuminate\Cache\RateLimiting\Limit 클래스의 인스턴스입니다. 이 클래스에는 제한을 빠르게 정의할 수 있도록 도와주는 "빌더" 메서드가 포함되어 있습니다. 속도 제한기 이름은 원하는 문자열을 사용할 수 있습니다.
use Illuminate\Cache\RateLimiting\Limit;use Illuminate\Http\Request;use Illuminate\Support\Facades\RateLimiter; /** * 모든 애플리케이션 서비스 부트스트랩. */protected function boot(): void{ RateLimiter::for('global', function (Request $request) { return Limit::perMinute(1000); });}
들어오는 요청이 지정된 속도 제한을 초과하면 Laravel에서 자동으로 429 HTTP 상태 코드가 포함된 응답이 반환됩니다. 속도 제한에 의해 반환되어야 하는 자체 응답을 정의하려면 response 메서드를 사용할 수 있습니다.
RateLimiter::for('global', function (Request $request) { return Limit::perMinute(1000)->response(function (Request $request, array $headers) { return response('Custom response...', 429, $headers); });});
속도 제한기 콜백은 들어오는 HTTP 요청 인스턴스를 받기 때문에 들어오는 요청 또는 인증된 사용자를 기반으로 적절한 속도 제한을 동적으로 빌드할 수 있습니다.
RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100);});
속도 제한 분할
때로는 임의의 값으로 속도 제한을 분할하고 싶을 수 있습니다. 예를 들어, 사용자가 주어진 경로에 IP 주소당 분당 100회 액세스하도록 허용할 수 있습니다. 이를 위해 속도 제한을 빌드할 때 by 메서드를 사용할 수 있습니다.
RateLimiter::for('uploads', function (Request $request) { return $request->user()->vipCustomer() ? Limit::none() : Limit::perMinute(100)->by($request->ip());});
이 기능을 다른 예로 설명하기 위해 인증된 사용자 ID당 분당 100회 또는 게스트의 경우 IP 주소당 분당 10회로 경로 액세스를 제한할 수 있습니다.
RateLimiter::for('uploads', function (Request $request) { return $request->user() ? Limit::perMinute(100)->by($request->user()->id) : Limit::perMinute(10)->by($request->ip());});
다중 속도 제한
필요한 경우 지정된 속도 제한기 구성에 대한 속도 제한 배열을 반환할 수 있습니다. 각 속도 제한은 배열 내에 배치된 순서에 따라 라우트에 대해 평가됩니다.
RateLimiter::for('login', function (Request $request) { return [ Limit::perMinute(500), Limit::perMinute(3)->by($request->input('email')), ];});
동일한 by 값으로 분할된 여러 속도 제한을 할당하는 경우 각 by 값이 고유한지 확인해야 합니다. 이를 달성하는 가장 쉬운 방법은 by 메서드에 제공된 값에 접두사를 붙이는 것입니다.
RateLimiter::for('uploads', function (Request $request) { return [ Limit::perMinute(10)->by('minute:'.$request->user()->id), Limit::perDay(1000)->by('day:'.$request->user()->id), ];});
라우트에 속도 제한기 연결
속도 제한기는 throttle 미들웨어를 사용하여 라우트 또는 라우트 그룹에 연결할 수 있습니다. throttle 미들웨어는 라우트에 할당하려는 속도 제한기의 이름을 받습니다.
Route::middleware(['throttle:uploads'])->group(function () { Route::post('/audio', function () { // ... }); Route::post('/video', function () { // ... });});
Redis로 스로틀링
기본적으로 throttle 미들웨어는 Illuminate\Routing\Middleware\ThrottleRequests 클래스에 매핑됩니다. 그러나 Redis를 애플리케이션의 캐시 드라이버로 사용하는 경우 Laravel에 Redis를 사용하여 속도 제한을 관리하도록 지시할 수 있습니다. 이렇게 하려면 애플리케이션의 bootstrap/app.php 파일에서 throttleWithRedis 메서드를 사용해야 합니다. 이 메서드는 throttle 미들웨어를 Illuminate\Routing\Middleware\ThrottleRequestsWithRedis 미들웨어 클래스에 매핑합니다.
->withMiddleware(function (Middleware $middleware) { $middleware->throttleWithRedis(); // ...})
폼 메서드 스푸핑
HTML 폼은 PUT, PATCH 또는 DELETE 작업을 지원하지 않습니다. 따라서 HTML 폼에서 호출되는 PUT, PATCH 또는 DELETE 라우트를 정의할 때 폼에 숨겨진 _method 필드를 추가해야 합니다. _method 필드와 함께 전송된 값은 HTTP 요청 메서드로 사용됩니다.
<form action="/example" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"></form>
편의를 위해 @method Blade 지시어를 사용하여 _method 입력 필드를 생성할 수 있습니다.
<form action="/example" method="POST"> @method('PUT') @csrf</form>
현재 라우트 액세스
Route 파사드의 current, currentRouteName, currentRouteAction 메서드를 사용하여 들어오는 요청을 처리하는 라우트에 대한 정보에 액세스할 수 있습니다.
use Illuminate\Support\Facades\Route; $route = Route::current(); // Illuminate\Routing\Route$name = Route::currentRouteName(); // string$action = Route::currentRouteAction(); // string
라우터 및 라우트 클래스에서 사용할 수 있는 모든 메서드를 검토하려면 Route 파사드의 기본 클래스와 Route 인스턴스에 대한 API 문서를 참조할 수 있습니다.
교차 출처 리소스 공유 (CORS)
Laravel은 구성한 값으로 CORS OPTIONS HTTP 요청에 자동으로 응답할 수 있습니다. OPTIONS 요청은 애플리케이션의 전역 미들웨어 스택에 자동으로 포함되는 HandleCors 미들웨어에 의해 자동으로 처리됩니다.
때로는 애플리케이션의 CORS 구성 값을 사용자 지정해야 할 수 있습니다. config:publish Artisan 명령어를 사용하여 cors 구성 파일을 게시하여 이 작업을 수행할 수 있습니다.
php artisan config:publish cors
이 명령어는 애플리케이션의 config 디렉토리 내에 cors.php 구성 파일을 생성합니다.
CORS 및 CORS 헤더에 대한 자세한 내용은 MDN 웹 문서의 CORS를 참조하십시오.
라우트 캐싱
프로덕션 환경에 애플리케이션을 배포할 때 Laravel의 라우트 캐시를 활용해야 합니다. 라우트 캐시를 사용하면 애플리케이션의 모든 라우트를 등록하는 데 걸리는 시간이 크게 줄어듭니다. 라우트 캐시를 생성하려면 route:cache Artisan 명령어를 실행하십시오:
php artisan route:cache
이 명령어를 실행하면 캐시된 라우트 파일이 모든 요청 시 로드됩니다. 새 라우트를 추가하면 새로운 라우트 캐시를 생성해야 한다는 점을 기억하십시오. 이러한 이유로 route:cache 명령어는 프로젝트 배포 중에만 실행해야 합니다.
route:clear 명령어를 사용하여 라우트 캐시를 지울 수 있습니다:
php artisan route:clear