In questa lezione vedremo come Laravel permette di gestire con una singola rotta URI in cui sono presenti elementi variabili. Ciò consente di semplificare le proprie rotte ed, ovviamente, poter creare una struttura di URL coerente anche per quelle situazioni in cui la pagina dipende dalla effettiva presenza di un contenuto su un database.
Come esempio, basti pensare alla pagina per accedere al contenuto di uno specifico post su un blog, o uno specifico ordine su un sito di e-commerce. Sebbene sia possibile recuperare tali contenuti indicando l’identificativo del post o dell’ordine tramite query string, ci sono situazioni in cui è desiderabile avere tale identificativo direttamente nel path della URI.
La possibilità di definire rotte con porzioni dinamiche del path della URI ci permette di:
- creare URI più semplici rispetto alle analoghe con query string, che sono anche in linea con le buone pratiche SEO (per esempio https://www.example.com/blog/45887 invece di https://www.example.com/blog/post?id=45887)
- essere coerenti con le buone pratiche delle API RESTful: GET https://www.example.com/api/order/03bd7e9c
- gestire porzioni “intermedie” del path, per esempio https://www.example.com/blog/topic/lifestyle/posts/ e https://www.example.com/blog/topic/comedy/posts/
Laravel permette di creare pagine web e risorse in grado di gestire queste situazioni in modo semplice e immediato tramite specifiche definizioni di rotte.
Rotte con parametri in Laravel
Nel definire una rotta è possibile istruire Laravel per fare in modo che una porzione della URI sia considerata variabile e venga catturata e messa a disposizione della funzione di callback. Vediamo un esempio:
Route::get('/blog/{id}', function ($id) { return 'This is the post '.$id; });
Rispetto alla definizione di una rotta statica (cioè una rotta che accetta solo un possibile path), possiamo notare che:
- nella stringa che rappresenta il path, la parte variabile è compresa tra due parentesi graffe ({id})
- nella funzione di callback è presente un parametro ($id)
È anche importante sapere che:
- per le parti variabili del path, comprese tra {}, è possibile usare solo lettere e _
- è possibile indicare più parti variabili, che verranno poi associate ai parametri della callback in base all’ordine (non è, quindi, necessario usare gli stessi nomi)
Route::get('/posts/{post_id}/comments/{comment_id}', function ($post, $commentId) { return 'This is the comment '.$commentId.' for post '.$post; });
Rotte con parametri opzionali in Laravel
Nel caso in cui sia necessario registrare un parametro di rotta opzionale, è sufficiente aggiungere un ? dopo il nome del parametro e indicare il valore di default di tale parametro
Route::get('/blog/{id?}', function ($id = 100) { return 'This is the post '.$id; });
Validazione dei parametri in Laravel
Nel caso sia necessario validare il valore ricevuto per il parametro, Laravel offre un modo conveniente per definire tale validazione. È possibile, infatti, concatenare il metodo where alla definizione della rotta indicando, come nome della where, il nome del parametro e una espressione regolare di validazione. Ogni parte variabile della url può avere la sua validazione.
Nel caso in cui la richiesta non soddisfi la validazione, Laravel risponderà con un risposta 404 Not Found.
// by_type può essere costituito solo da lettere minuscole Route::get('/blog/topic/{by_type}/posts/', function ($type) { // })->where('by_type', '[a-z]+'); // id può essere costituito solo da numeri Route::get('/blog/{id}', function ($id) { return 'This is the post '.$id; })->where('id', '[0-9]+');
Nel caso di parametri multipli, è possibile indicare una validazione per ciascuno di essi:
Route::get('/posts/{post_id}/comments/{comment_id}', function ($postId, $commentId) { // })->where(['post_id' => '[0-9]+', 'comment_id' => '[a-z0-9]+']);
Oltre a fornire una espressione regolare per il controllo di validità, sono disponibili dei metodi helper per aggiungere rapidamente validazioni dei casi più comuni:
// by_type può essere costituito solo da lettere minuscole Route::get('/blog/topic/{by_type}/posts/', function ($type) { // })->whereAlpha('by_type'); // id può essere costituito solo da numeri Route::get('/blog/{id}', function ($id) { return 'This is the post '.$id; })->whereNumber('id');
In caso di più parametri è possibile concatenare diversi helper, uno per parametro.
Parametri e dependency injection in Laravel
Per utilizzare una dipendenza esterna nella funzione di callback di una route con parametri, è necessario indicare i parametri con dependency injection prima dei parametri di rotta.
use Illuminate\Http\Request; Route::get('/posts/{id}/comments', function (Request $request, $id) { $order = $request->query('order_by'); // recupera i commenti in base al criterio // $comments = Comments:findBy($id)->orderBy($order); // ... });