Laravel Routing

정종일·2023년 10월 19일
0

Laravel

목록 보기
8/9

Basic Routing

use Illuminate\Support\Facades\Route;
 
Route::get('/greeting', function () {
    return 'Hello World';
});

The Default Route Files

routes 폴더 내에 정의된 route 파일들은 애플리케이션의 RouteServiceProvider에 의해 자동으로 로드된다. routes/web.php 파일에 정의된 route들은 web 미들웨어 그룹에 할당되고 세션이나 CSRF protection 같은 여러 기능들을 제공한다. routes/api.php 에 정의된 route들은 api 미들웨어 그룹에 할당된다.

RouteServiceProvider 에 의해 그룹핑된 routes/api.php 파일은 자동으로 주소 앞에 /api prefix가 붙기 때문에 따로 설정해주지 않아도 된다.

Available Route Methods

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를 사용할 수 있다

Route::match(['get', 'post'], '/', function () {
    // ...
});
 
Route::any('/', function () {
    // ...
});

match, any를 통해 여러 http 메서드를 동일 경로에 지정하는 경우 기본 http 메서드를 사용하는 routes들이 먼저 정의되어있어야 한다.

Dependency Injection

콜백 함수의 파라미터로 타입 힌트 의존성 주입이 가능하다.

use Illuminate\Http\Request;
 
Route::get('/users', function (Request $request) {
    // ...
});

Redirect Routes

Route::redirect 를 통해 uri에서 uri로 리다이렉팅 가능 / HTTP status code도 설정 가능

Route::redirect('/here', '/there');

Route::redirect('/here', '/there', 301);

Route::permanentRedirect('/here', '/there');

View Routes

view 파일만을 return 하려면 Route::view 를 사용하면 된다

Route::view('/welcome', 'welcome');
 
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

// URI, view name, parameters

The Route List

php artisan route:list

// route list 출력

php artisan route:list -v

// 각 route에 할당된 middleware도 출력

php artisan route:list --path=api

// 주어진 URI로 시작하는 route만 출력

php artisan route:list --except-vendor

// 서드파티 패키지에 의해 정의된 route는 제외하고 출력

php artisan route:list --only-vendor

// 서드파티 패키지에 의해 정의된 route만 출력

Route Parameters

Required Parameters

URI에 파라미터로 받을 변수 지정 가능

Route::get('/user/{id}', function (string $id) {
    return 'User '.$id;
});

Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
    // ...
});

Parameters & Dependency Injection

의존성을 주입해야 한다면 route parameter보다 앞에 정의할 것

use Illuminate\Http\Request;
 
Route::get('/user/{id}', function (Request $request, string $id) {
    return 'User '.$id;
});`

Optional Parameters

? 를 통해 파라미터를 옵셔널하게 받을 수 있다

Route::get('/user/{name?}', function (?string $name = null) {
    return $name;
});
 
Route::get('/user/{name?}', function (?string $name = 'John') {
    return $name;
});

Regular Expression Constraints

패턴에 맞지 않는 요청이 들어오면 404 에러 리턴

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']);

Global Constraints

파라미터에 대한 제약을 걸고싶다면 RouteServiceProvider 내 boot 메서드에 pattern 메서드를 통해 정의

/**
 * Define your route model bindings, pattern filters, etc.
 */
public function boot(): void
{
    Route::pattern('id', '[0-9]+');
}

Named Routes

각 routes에 name 지정 가능

Route::get('/user/profile', function () {
    // ...
})->name('profile');

Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
)->name('profile');

// 특정 controller의 메서드에 할당도 가능하다 (unique)

Generating URLs To Named Routes

// Generating URLs...
$url = route('profile');
 
// Generating Redirects...
return redirect()->route('profile');
 
return to_route('profile');

Route::get('/user/{id}/profile', function (string $id) {
    // ...
})->name('profile');
 
$url = route('profile', ['id' => 1]);

Route::get('/user/{id}/profile', function (string $id) {
    // ...
})->name('profile');
 
$url = route('profile', ['id' => 1, 'photos' => 'yes']);
 
// /user/1/profile?photos=yes

Inspecting The Current Route

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
/**
 * Handle an incoming request.
 *
 * @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);
}

Route Groups

route들에 middleware를 공통으로 적용하기 위해서는 middleware 메서드를 사용하면 된다

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // Uses first & second middleware...
    });
 
    Route::get('/user/profile', function () {
        // Uses first & second middleware...
    });
});

Controllers

controller 메서드로 동일한 controller를 사용하는 route들을 그룹화할 수 있다

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 (string $account, string $id) {
        // ...
    });
});

Route Prefixes

그룹화한 모든 route에 prefix 적용

Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // Matches The "/admin/users" URL
    });
});

Route Name Prefixes

name 메서드로 route name의 prefix도 지정이 가능

Route::name('admin.')->group(function () {
    Route::get('/users', function () {
        // Route assigned name "admin.users"...
    })->name('users');
});

Route Model Binding

Implicit Binding

파라미터에 쿼리스트링으로 들어온 변수를 의존성 주입을 통해 타입힌트 해놓으면 Eloquent가 model ID를 통해 자동으로 바인딩하는 기능

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
    return $user->email;
});

만약 매칭되는 모델이 없다면 404 에러 리턴

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]);
}

Controller에서도 가능

Customizing The Key

자동 매칭 시 ID 대신 다른 속성을 사용할 수도 있다

use App\Models\Post;
 
Route::get('/posts/{post:slug}', function (Post $post) {
    return $post;
});

만약 계속해서 해당 속성으로 바인딩하고 싶다면 Eloquent 모델에

/**
 * Get the route key for the model.
 */
public function getRouteKeyName(): string
{
    return 'slug';
}

해당 옵션으로 사용이 가능하다

Implicit Enum Binding

enum 타입도 바인딩 가능

<?php
 
namespace App\Enums;
 
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

use App\Enums\Category;
use Illuminate\Support\Facades\Route;
 
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
profile
제어할 수 없는 것에 의지하지 말자

5개의 댓글

comment-user-thumbnail
2025년 1월 10일

ho

답글 달기
comment-user-thumbnail
2025년 1월 10일

ho

답글 달기
comment-user-thumbnail
2025년 1월 10일

ho

답글 달기
comment-user-thumbnail
2025년 1월 10일

ho

답글 달기
comment-user-thumbnail
2025년 5월 13일

유용한 정보를 제공해 주셔서 감사합니다.
slice master

답글 달기