Quando si parla di backend, chi sviluppa deve fare i conti con le route. Le route possono essere considerate la spina dorsale del backend, poiché ogni richiesta che il server riceve viene reindirizzata a un controller attraverso un elenco di routing che mappa le richieste ai controller o alle azioni.
Laravel ci nasconde molti dettagli di implementazione e include molto zucchero sintattico per aiutare sia chi è agli inizi con lo sviluppo che le persone più esperte a sviluppare le loro applicazioni web.
Vediamo nel dettaglio come gestire le route in Laravel.
Routing e Cross-Site Scripting in Laravel
Su un server esistono route pubbliche e private. Le route pubbliche possono essere fonte di preoccupazione a causa della possibilità di cross-site scripting (XSS), un tipo di attacco a injection che può lasciare voi e i vostri utenti vulnerabili a soggetti malintenzionati.
Il problema è che un utente può essere reindirizzato da una route che non richiede un token di sessione a uno che invece lo richiede, continuando ad avere accesso senza il token.
Il modo più semplice per risolvere questo problema è quello di applicare un nuovo heading HTTP, aggiungendo “referrer” al percorso per mitigare questo scenario:
'main' => [
'path' => '/main',
'referrer' => 'required,refresh-empty',
'target' => ControllerDashboardController::class . '::mainAction'
]
Routing di Base in Laravel
In Laravel, i percorsi consentono agli utenti di indirizzare la richiesta appropriata al controller desiderato. La route Laravel più semplice accetta un Identificatore Uniforme di Attività (il percorso del routing) e una chiusura che può essere sia una funzione che una classe.
In Laravel, le route vengono create all’interno dei file web.php e api.php. Laravel è dotato di due route predefinite: una per il WEB e una per l’API.
Queste route si trovano nella cartella routes/, ma vengono caricate nel file Providers/RouteServiceProvider.php.
Invece di fare questo, possiamo caricare le route direttamente all’interno di RouteServiceProvider.php, saltando completamente la cartella routes/.
Reindirizzamenti
Quando definiamo una route, di solito vogliamo reindirizzare l’utente che vi accede e le ragioni di questa scelta variano molto. Può essere perché si tratta di una route deprecata e abbiamo cambiato il backend o il server, oppure perché vogliamo installare l’autenticazione a due fattori (2FA) e così via.
Laravel offre un modo semplice per farlo. Grazie alla semplicità del framework, possiamo usare il metodo redirect della facciata Route, che accetta la route di ingresso e quella verso cui essere reindirizzati.
Facoltativamente, possiamo indicare il codice di stato per il reindirizzamento come terzo parametro. Il metodo permanentRedirect
avrà la stessa funzione del metodo redirect
, con la differenza che restituirà sempre un codice di stato 301:
// Simple redirect
Route::redirect("/class", "/myClass");
// Redirect with custom status
Route::redirect("/home", "/office", 305);
// Route redirect with 301 status code
Route::permanentRedirect("/home", "office");
All’interno delle route di reindirizzamento è vietato usare le parole chiave “destination” e “status” come parametri perché sono riservate da Laravel.
// Illegal to use
Route::redirect("/home", "/office/{status}");
Viste
Le viste sono i file .blade.php che usiamo per rendere il frontend della nostra applicazione Laravel. Si serve del motore di template blade ed è il modo predefinito per costruire un’applicazione full-stack utilizzando solo Laravel.
Se vogliamo che la nostra route restituisca una vista, possiamo semplicemente usare il metodo view della facciata Route. Questo metodo accetta un parametro di route, un nome di vista e un array opzionale di valori da passare alla vista.
// When the user accesses my-domain.com/homepage
// the homepage.blade.php file will be rendered
Route::view("/homepage", "homepage");
Supponiamo che la nostra vista voglia dire “Ciao, {name}
” passando un array opzionale con quel parametro. Possiamo farlo con il seguente codice (se il parametro mancante è richiesto dalla vista, la richiesta fallirà e verrà lanciato un errore):
Route::view('/homepage', 'homepage', ['name' => "Kinsta"]);
Elenco delle Routes
Con l’aumentare delle dimensioni della vostra applicazione, aumenterà anche il numero di richieste da instradare. E con una grande quantità di informazioni può nascere una grande confusione.
È qui che il sito artisan route:list command
può aiutarci. Fornisce una panoramica di tutte le route definite nell’applicazione, dei relativi middleware e dei controller.
php artisan route:list
Mostra un elenco di tutte le route senza i middleware. A questo scopo, dobbiamo usare il flag -v
:
php artisan route:list -v
In una situazione in cui si usa una progettazione orientata al dominio in cui i percorsi hanno nomi specifici nei loro percorsi, potete usare le capacità di filtraggio di questo comando in un modo simile:
php artisan route:list –path=api/account
Così verranno mostrati solo le route che iniziano con api/account.
D’altra parte, possiamo indicare a Laravel di escludere o includere le route definite da terzi con le opzioni –except-vendor
o –only-vendor
.
Parametri delle Routes
A volte potreste aver bisogno di catturare segmenti dell’URI con la route, come un ID utente o un token. Possiamo farlo definendo un parametro di route, che è sempre racchiuso tra parentesi graffe ({}
) e deve essere composto solo da caratteri alfabetici.
Se le nostre route hanno delle dipendenze all’interno delle loro callback, il contenitore di servizi Laravel le inietterà automaticamente:
use IlluminateHttpRequest;
use Controllers/DashboardController;
Route::post('/dashboard/{id}, function (Request $request, string $id) {
return 'User:' . $id;
}
Route::get('/dashboard/{id}, DashboardController.php);
Parametri Richiesti
I parametri obbligatori di Laravel sono parametri delle route che non possiamo saltare quando effettuiamo una chiamata. In caso contrario, verrà lanciato un errore:
Route::post("/gdpr/{userId}", GetGdprDataController.php");
Ora all’interno di GetGdprDataController.php avremo accesso diretto al parametro $userId.
public function __invoke(int $userId) {
// Use the userId that we received…
}
Una route può contenere un numero qualsiasi di parametri. Questi vengono iniettati nei callback/controller della route in base all’ordine in cui sono elencati:
// api.php
Route::post('/gdpr/{userId}/{userName}/{userAge}', GetGdprDataController.php);
// GetGdprDataController.php
public function __invoke(int $userId, string $userName, int $userAge) {
// Use the parameters…
}
Parametri Opzionali
Se vogliamo fare qualcosa in una route quando è presente solo un parametro e nient’altro, senza influenzare l’intera applicazione, possiamo aggiungere un parametro opzionale. Questi parametri opzionali sono contrassegnati dal simbolo ?
:
Route::get('/user/{age?}', function (int $age = null) {
if (!$age) Log::info("User doesn't have age set");
else Log::info("User's age is " . $age);
}
Route::get('/user/{name?}', function (int $name = "John Doe") {
Log::info("User's name is " . $name);
}
Carattere Jolly della Route
Laravel ci offre un modo per filtrare l’aspetto dei nostri parametri opzionali o obbligatori.
Supponiamo di volere una stringa di un ID utente. Possiamo convalidarla in questo modo a livello di route usando il metodo where
.
Il metodo where
accetta il nome del parametro e la regola regex che verrà applicata alla convalida. Per impostazione predefinita, accetta il primo parametro, ma se ne abbiamo molti, possiamo passare un array con il nome del parametro come chiave e la regola come valore e Laravel li analizzerà tutti per noi:
Route::get('/user/{age}', function (int $age) {
//
}->where('age', '[0-9]+');
Route::get('/user/{age}', function (int $age) {
//
}->where('[0-9]+');
Route::get('/user/{age}/{name}', function (int $age, string $name) {
//
}->where(['age' => '[0-9]+', 'name' => '[a-z][A-z]+');
Possiamo fare un ulteriore passo avanti e applicare la convalida a tutti i percorsi della nostra applicazione utilizzando il metodo pattern
sulla facciata Route
:
Route::pattern('id', '[0-9]+');
Questo metodo convaliderà ogni parametro di id
con questa espressione regex. Una volta definita, verrà applicata automaticamente a tutte le route che usano quel nome di parametro.
Come possiamo vedere, Laravel usa il carattere /
come separatore nel percorso. Se vogliamo usarlo nel percorso, dobbiamo consentire esplicitamente che faccia parte del nostro segnaposto utilizzando una regex where
.
Route::get('/find/{query}', function ($query) {
//
})->where('query', , '.*');
L’unico inconveniente è che sarà supportato solo nell’ultimo segmento del percorso.
Routes con Nome
Come suggerisce il nome, possiamo dare un nome alle route, il che rende conveniente generare URL o reindirizzamenti per route specifiche.
Come Creare Route con Nome
Un modo semplice per creare una route con nome è fornito dal metodo name
concatenato alla facciata Route
. Il nome di ogni route deve essere unico:
Route::get('/', function () {
})->name("homepage");
Gruppi di Routes
I gruppi di route vi permettono di condividere i loro attributi, come i middleware, su un gran numero di route senza doverli ridefinire su ogni singola route.
Middleware
Assegnare un middleware a tutti i percorsi che abbiamo ci permette di combinarli in un gruppo, prima di tutto utilizzando il metodo group
. Una cosa da considerare è che i middleware vengono eseguiti nell’ordine in cui vengono applicati al gruppo:
Route:middleware(['AuthMiddleware', 'SessionMiddleware'])->group(function () {
Route::get('/', function() {} );
Route::post('/upload-picture', function () {} );
});
Controller
Quando un gruppo usa lo stesso controller, possiamo usare il metodo controller
per definire il controller comune a tutte le route del gruppo. Ora dobbiamo specificare il metodo che la route chiamerà.
Route::controller(UserController::class)->group(function () {
Route::get('/orders/{userId}', 'getOrders');
Route::post('/order/{id}', 'postOrder');
});
Route del Sottodominio
Il nome di un sottodominio è un’informazione aggiuntiva che va all’inizio del nome di dominio di un sito web. Questo permette ai siti web di separare e organizzare i contenuti per funzioni specifiche, come negozi online, blog, presentazioni e così via, dal resto del sito.
Le nostre route si possono usare per gestire il routing dei sottodomini. Possiamo catturare il dominio e una porzione del sottodominio da usare nel nostro controller e nella nostra route. Con l’aiuto del metodo domain
sulla facciata Route
, possiamo raggruppare le nostre route sotto un unico dominio:
Route::domain('{store}.enterprise.com')->group(function() {
Route::get('order/{id}', function (Account $account, string $id) {
// Your Code
}
});
Prefissi e Prefissi dei Nomi
Ogni volta che abbiamo un gruppo di route, invece di modificarle una per una, possiamo usare le utilità extra che Laravel ci mette a disposizione, come per esempio prefix
e name
sulla facciata Route
.
Il metodo prefix
può essere utilizzato per prefissare ogni route del gruppo con un determinato URI, mentre il metodo name
si può usare per prefissare il nome di ogni route con una determinata stringa.
Questo ci permette di creare nuovi elementi come le route amministrative senza dover modificare ogni singolo nome o prefisso per identificarle:
Route::name('admin.")->group(function() {
Route::prefix("admin")->group(function() {
Route::get('/get')->name('get');
Route::put('/put')->name(put');
Route::post('/post')->name('post');
});
});
Ora gli URI per queste route saranno admin/get
, admin/put
, admin/post
e i nomi admin.get
, admin.put
e admin.post
.
Caching delle Routes
Quando distribuisce l’applicazione sui server di produzione, un buon sviluppatore Laravel sfrutta la cache delle route di Laravel.
Cos’È la Cache delle Routes?
La cache delle route riduce il tempo necessario per registrare tutte le route dell’applicazione.
Eseguendo php artisan route:cache
viene generata un’istanza di Illuminate/Routing/RouteCollection
e, dopo essere stata codificata, l’output serializzato viene scritto in bootstrap/cache.routes.php
.
Ora qualsiasi altra richiesta caricherà questo file di cache, se esiste. Pertanto, la nostra applicazione non deve più analizzare e convertire le voci del file dei percorsi in oggetti Illuminate/Routing/Route
in Illuminate/Routing/RouteCollection
.
Perché È Importante Usare la Cache delle Routes
Se non usate la funzione di caching delle route offerta da Laravel, la vostra applicazione rischia di funzionare più lentamente di quanto potrebbe, con il rischio di ridurre le vendite, la fidelizzazione degli utenti e la fiducia nel vostro marchio.
A seconda della scala del vostro progetto e del numero di route, l’esecuzione di un semplice comando di caching delle route può accelerare la vostra applicazione dal 130% al 500%: un guadagno enorme a fronte di uno sforzo quasi nullo.
Riepilogo
Il routing è la spina dorsale dello sviluppo backend. Il framework Laravel eccelle in questo senso, fornendo un modo verboso di definire e gestire i percorsi.
Lo sviluppo può essere accessibile a chiunque e contribuire a velocizzare un’applicazione solo in virtù del fatto che è stata realizzata in Laravel.
Quali altri trucchi e suggerimenti avete riscontrato riguardo alle rotte di Laravel? Fatecelo sapere nella sezione commenti!
Lascia un commento