Laravel e le routes


laravel-e-le-routes

In Laravel, il file routes.php è la mappa che guida le richieste ricevute tramite URL verso le risorse restituite dall'applicazione. E' uno strumento ricco di funzionalità: in questa panoramica potrai trovarne alcune.

Il routing

Il routing o instradamento, in un'infrastruttura di rete, è la selezione del miglior percorso verso una porta o un'interfaccia.
In Laravel, il routing ti permette, ad esempio, di collegare una richiesta, fornita tramite URL via GET o via POST, al metodo del controller che restituisce una view.
Si possono specificare i verbi HTTP con i quali la richiesta è formulata, si possono definire le regole a cui deve sottostare per arrivare fino al metodo del controller (con i middleware) e si possono anche raggruppare una serie di instradamenti con caratteristiche comuni (come ad esempio le risorse accessibili dietro autenticazione).

Il file routes.php

Tutte le routes vanno inserite nel file app/Http/routes.php.
Questo file viene richiamato dal metodo mapWebRoutes() nel RouteServiceProvider (app/Providers/RouteServiceProviders.php) in cui viene passata un'istanza della classe Router; viene definito per le routes il namespace dell'applicazione e viene impostato il middleware web, una collezione di altri middleware, tra cui quello per la verifica del CSRF.

La route più semplice

La route più semplice è quella con la callback:

Route::get('route_con_callback', function() {
    echo 'Ecco una route con callback';
});

Laravel prenderà in ingresso l'url www.miodominio.local/public/route_con_callback e stamperà a video Ecco una route con callback

Questo tipo di routes sono molto utili per alcuni tipi di situazioni:

  • view statiche
  • situazioni in cui c'è bisogno di restituire una risposta al client velocemente (ad esempio un redirect o un errore 404)
  • situazioni temporanee di debug

Nonostante sia possibile, non puoi pensare di realizzare tutta la logica della tua applicazione nel file routes.php. Devi applicare lo stesso approccio che applicava Cesare: "divide et impera", dividi e comanda. Non si riferiva ovviamente ai software, ma la sapeva lunga, Giulio, e dividere la logica della tua applicazione in parti separate è un'ottima strategia.

Anatomia di una route

La route precedente è formata da:

  • Route:: : la facade per accedere ai metodi della classe Router;
  • get : il metodo (o verbo) HTTP con cui viene effettuata la richiesta;
  • function(){...} : la callback che stampa a video la stringa.

Se vuoi collegare la tua route ad una funzione nel controller, al posto della callback, passa come stringa la classe e il metodo del tuo controller, nel formato Classe@metodo: Route::get('route_al_metodo', 'MiaClasse@metodo');

I metodi HTTP

In Laravel puoi usare 7 metodi:

  • GET (Route::get($uri, $callback);
  • HEAD (Route::post($uri, $callback);
  • PUT (Route::put($uri, $callback);
  • PATCH (Route::patch($uri, $callback);
  • DELETE (Route::delete($uri, $callback);
  • OPTIONS (Route::options($uri, $callback).

In più, puoi utilizzare anche altri due metodi aggiuntivi:

  • Route::match(['get', 'post', '...'], '/', function () {...});: per far sì che metodi differenti restituiscano la stessa risorsa;
  • Route::any('url_richiesta', function () {...});: per indicare che la risorsa dev'essere restituita per qualsiasi metodo.

Perciò, nella maggior parte dei casi, se dovessi mostrare una pagina, userai Route::get(...), se dovessi gestire l'invio di un form userai invece Route::post(...), e così via.
Se ancora non conosci i verbi HTTP, puoi farti un'idea a questo link.

I parametri nelle routes

Hai un blog e devi creare la route per visualizzare il 42° post del tuo blog, l'URL richiesta potrebbe essere la seguente:
www.bellissimonomedelblog.ext/posts/42

La route per gestire la richiesta sarà quindi questa:
Route::get('posts/{id}', 'PostController@show');

Come puoi vedere, l'identificativo dell'articolo viene indicato nella route con la sintassi {id}.
Laravel passerà in maniera implicita il parametro alla funzione nel controller.

Nel caso il parametro sia opzionale, si usa il simbolo ? dopo il nome del parametro: Route::get('ricerca_id_post/{id?}', 'PostController@ricerca'); Ovviamente, nella funzione del controller la possibile assenza del parametro dev'essere gestita, altrimenti verrà sollevata un'eccezione ErrorException di argomento mancante.

Puoi passare tutti i parametri che vuoi, con la stesso criterio di cui sopra.

Regular Expression e Global Constraints

Se avessi bisogno di specificare il formato del parametro che può essere passato alla route, puoi scegliere tra due soluzioni:

  • concatenando il metodo where alla route: Route::get('posts/{id}', 'PostController@show')->where('id', '[0-9]+');
  • aggiungendo al metodo boot, in app/Providers/RouteServiceProvider, il pattern necessario: $router->pattern('id', '[0-9]+');

Nell'esempio sopra, indipendentemente dalla soluzione scelta, l'identificativo verrà accettato solo se composto da caratteri numerici. In caso contrario, verrà sollevata un'eccezione NotFoundHttpException.

Model binding

In alcune situazioni, come quella precedente in cui viene recuperato un post, può essere utile ricorrere al model binding, passando un'istanza della classe che si occupa di reperire il post.
Laravel si occuperà di trovare il record corrispondente cercando nella tabella del database il post con campo 'id' uguale al valore del parametro passato.

Se la route contiene una callback, la classe va inserita come parametro della funzione:

Route::get('post/{post}', function (App\Post $post) {
    return $post->titolo;
});

Se invece si passa il collegamento al metodo di un controller, l'istanza del Model va passata come parametro del metodo nel controller.
Ricordati che il nome del parametro dev'essere lo stesso dell'istanza della classe: solo così Laravel esegue il binding in automatico.

Le named routes

Questa funzionalità ti permette di nominare le route per richiamarle all'interno della tua applicazione.
Route::get('posts', ['as' => 'articoli', 'uses' => 'PostController@index']);
La sintassi è semplice: basta passare un array come secondo parametro.
In esso, usa come chiave as e come valore il nome che vuoi usare per la route, nel caso sopra, articoli.
Sempre nello stesso array, puoi passare il collegamento al metodo del controller come valore della chiave uses.

Un'alternativa a questa sintassi è l'uso del metodo name() al termine della route: Route::get('posts', 'PostController@index')->name('articoli');

Attenzione, però: se come URL usi /articoli riceverai un'eccezione di route non trovata. Questo perchè le named routes servono solo all'interno del sistema.
Per i collegamenti interni puoi usare l'helper route('articoli') per raggiungere la route.

Route Groups

Se alcune routes condividono un prefisso, o hanno un middleware in comune, come quello dell'autenticazione, possono essere raggruppate in un Route Group.

Route::group(['prefix' => 'intranet/', 'middleware' => 'auth'], function () {
    Route::get('/dashboard', function ()    {
        ...
    });

    Route::get('posts', function () {
        ...
    });
});

Nell'esempio precedente, tutte le route facenti parte del gruppo, hanno come prefisso /intranet/ ed hanno come middleware auth, per il controllo dell'autenticazione.

Artisan

Artisan ti mette a disposizione solo 3 comandi, ma davvero preziosi:

  • artisan route:list: ti consente di visualizzare la lista delle route presenti, e per ognuna indica dominio, metodo HTTP, URI, nome, azione e middleware applicato/i. Puoi anche filtrarle per metodo aggiungendo alla fine del comando --method=GET, ad esempio;
  • artisan route:cache: ti dà la possibilità di creare un file in cache per velocizzare il processo di routing. (funziona solo se le route non hanno una callback);
  • artisan route:clear: per eliminare il file di routing nella cache.

Conclusioni

In questa panoramica hai visto le principali caratteristiche del routing di Laravel.
Non è ovviamente un trattato esaustivo sull'argomento e ci sono altre funzionalità che puoi approfondire: ti propongo qualche link qui di seguito.

APPROFONDIMENTI

Blog tags


Cerca un post


Ultimi tweet


pubblicato il {{ tweet.created_at | formattaData }}