w3resource

Laravel (5.7) Routing

One of the coolest features in laravel framework is it’s routing feature. Routing is the ability to map URL requests to specific routes. It is simply a way of creating a request URL of your application. In Laravel, all requests are mapped with the help of routes. Basic routing routes the request to the associated controllers. We will be examining routing in detail under these sub-topics.

  • Basic Routing
    - Redirect Routes
    - View Routes
  • Route Parameters
    - Required Parameters
    - Optional Parameters
  • Named Routes
  • Route Groups
    - Middleware
    - Namespaces
  • Route Model Binding
    - Implicit Binding
    - Explicit Binding
  • Fallback Routes
  • Form Method Spoofing
  • Accessing The Current Route

Basic Routing

All the routes in a laravel application are registered within routes/web.php file. When you set up a laravel project with the laravel new app command, the major app directory contains a routes subdirectory which contains the web.php file where the routes are defined. Initially, the web.php  file, should look like this;

Route::get('/', function () {
   return view('welcome');
});

The code snippet above tells the browser to return the welcome view when the default URL is entered. The views are found in the resources/views directory. In this case, the request maps to resources/views/welcome.blade.php file. The most common pattern of defining routes is to attach the specified route to the associated controller which handles all of the action taking place within the route. For example;

Route::get('/user', 'UserController@index');

So this associates the '/user', with the 'UserController@index' controller. The URI (uniform resource identifier) in this case in the '/user', while the corresponding callback function is the 'UserController@index' controller.

Available Router Methods

The router allows you to register routes that respond to any 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);

Redirect Routes

There are different methods that laravel provides on the Route facade.One of them is the redirect method. As the method name implies,this method is useful when you are defining a URI that redirects to another route. Here is how it is used;

Route::redirect('/user', '/admin');

This means that if you try accessing the '/user' route, you will be redirected to the '/admin' route. Isn't that nice?

View Routes

Another method available to the Route facade is the view method. This method is only useful when your route only returns a view. The view method accepts two required arguments and one optional argument. The first is the URI you are targeting and the second is the name of the view you want to display.

Route::view('/user', 'user');

Route Parameters

Route parameters are named URL segments that are used to capture the values specified at their position in the URL. There are two ways of defining route parameters in laravel. They are;

Required Parameters

As the name implies, these are parameters that should be compulsorily captured for routing the web application. For example, a user's identification number.

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

These parameters are injected as arguments in the route callbacks

Optional Parameters

The major difference between the required parameters and the optional is the inclusion of a ? after the parameter name in the URL. It is also important to remember to specify a default value for the parameter name in the callback function. Here is what I mean;

Route::get('user/{name?}', function ($name = "John" ) {
   return 'My name is ' .$name;
});

Named Routes

Named routes allow a convenient way of creating routes. This is done by attaching the name method to the route definition.

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

The following code shows an example for creating named routes with a controller

Route::get('user/details', ''UserController@showDetails')->name('details');

Route Groups

Route groups enable sharing of route attributes, across a number of routes without necessarily defining those attributes on each individual route. Shared attributes are specified in an array format as the first parameter to the Route::group method. As seen below;

Route::group(['namespace' => 'Admin', 'prefix' => 'admin')(function () {
    Route::get('/', function () {});

Middleware

Using the middleware method on the Route facade, you can assign middleware to all the routes within a group.

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

    Route::get('user/profile', function () {
       // Uses first & second Middleware
    });
});

Namespaces

Using the namespace method, you can register a group controller using the same PHP namespace. This is another use of route groups.

Route::namespace('Admin')->group(function () {
   // Controllers Within The "App\Http\Controllers\Admin" Namespace
});

Route Model Binding

Route model binding in Laravel provides a mechanism to inject a model instance into your routes. Say we want to get a post from the database, we could do something like this:

Route::get('posts/{id}', function ($id) {
       // we have to find the post using the $id
        $posts = Post::find($id);

       // if there is no post, 404
       if (!$posts) return abort(404);

      // return the view and the post
      return view('post.show', compact('post'));

    });

But route model binding helps us get rid of extra keystrokes by simplifying the instance above into

Route::get('posts/{post}', function ($post) {

    // we now have access to the $post object! no code necessary

    // return the view and the post
    return view('post.show', compact('post'));
});

This is made possible by telling Laravel to inject a Post model into any route controller that has a {post} parameter attached to it.

There are two types of model binding in Laravel. Implicit Binding and Explicit Binding

Implicit Binding

Route::get('posts/{post}', function (App\Post $post) {
    // be awesome. enjoy having the $post object
});

Laravel knows that since a Post model is being injected into the controller closure, it should get the id parameter from the route and get the details for the user.

Changing the Model's Route key

If you would like the implicit model binding to use a database column other than id when retrieving models, you may override the getRouteKeyName method on your Eloquent model. For instance, if we wanted to use the slug instead of the id, we could do the following:

class Post extends Model {
    public function getRouteKeyName() {
        return 'slug';
    }
}

Explicit Binding

Just like the name implies, you have to explicitly tell laravel you want it to bind a URL parameter to a particular model. There are two ways to do this, we could bind a parameter to a model using the provided Route facade or carry out this binding in app/Providers/RouteServiceProvider.php.

Using the Route Facade

Using the Route facade to bind a parameter to a model, we can do something like this:

Route::bind('post', 'App\Post');

We could also give our binding more meaning, for example, what if we want a post only if is a draft? For that we could change the second parameter of the Route::bind to a closure which takes the route parameter as its value.

Route::bind('post', function ($value) {
    return App\Post::find($value)->where('status', '=', 'published')->first();
});

Using the RouteServiceProvider

The only difference between using the Route facade and RouteServiceProvider class is that - registering your bindings is done in the boot method of the RouteServiceProvider class (location is app/Providers directory) and the bind method is called on the $router object injected into the method. Quick example

public function boot(Router $router)
{
    parent::boot($router);

    $router->bind('post', function ($value) {
        return App\Post::find($value)->where('status', '=', 'published')->first();
    });
}

Fallback Routes

Using the fallback method on the Route facade, you can define a route that will be fallen back to when no other route matches the incoming request.

Route::fallback(function () {
   //
});

Form Method Spoofing

HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form. The value sent with the _method field will be used as the HTTP request method:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

Accessing The Current Route

You may use the current, currentRouteName, and currentRouteAction methods on the Route facade to access information about the route handling the incoming request:

$route = Route::current();

$name = Route::currentRouteName();

$action = Route::currentRouteAction();

Previous: Laravel (5.7) Contracts
Next: Laravel (5.7) Middleware



Follow us on Facebook and Twitter for latest update.