Poznajemy routing w Laravelu. Kontynuacja poprzednich lekcji w naszym projekcie. Zaczynajmy.

Ok, najpierw coś prostego – przekierowania:

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

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

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

Mamy też routes z callbackiem, które możemy dopisać pod konkretny route i konkretny HTTP verb:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Z ciekawszych mamy też any i match:

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

Ok, zobaczmy na route parameters (wrzucamy do web.php):

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

A jak to z requestem pogodzić? Request najpierw:

Route::get('/user/{id}', function (Request $request, string $id) {
    $page = $request->query('page', '1');
    return 'User '.$id . ' Page: ' . $page;
});

Route params mogą być nullable:

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

Z drugiej strony, mogą podlegać restrykcjom określonym w regex:

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

Mamy też pomocnicze funkcje do tego:

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());

W AppServiceProvider możemy stworzyć własne wzory:

use Illuminate\Support\Facades\Route;
 
/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Route::pattern('id', '[0-9]+');
}

Z ciekawszych rzeczy jakie widzę, jest możliwość sprawdzania nazwy route wewnątrz middleware:

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

A co to nazwa route? Już ją widzieliśmy, przypomnijmy:

Route::get('/faker', function () {
    return view('faker');
})->name("faker");


Route::get('/faker2', FakerController::class)->name("faker2");

Route::view('/faker3', 'faker')->name('faker3');

Mamy tutaj route z callbackiem, route z invokable controllerem oraz route z widokiem, wszystkie na metodzie get i wszystkie robią mniej więcej to samo. Ta nazwa to ten „name”. Dzięki niej możemy robić redirecty do tych routes:

Route::get('/', function () {
    
    return view('welcome2');
})->name("main");

Route::post("/", function(Request $request){
    $request->validate([
        'author' => 'required',
        'description' => 'required'
    ]);
    session()->flash("status", "entry created!");
    return redirect()->route("main");
});

Tutaj mamy przykład redirecta do nazwanego route. Choć można do redirect przekazać string ze ścieżką relatywną, np. „/”, to też zadziała.