Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use Laravel 5 Middleware to allow packages to override app routes?

I would like to be able to override the routes defined in app/Http/routes.php with a route in a package.

For example, in app/Http/routes.php I might have this:

Route::get('/search/{type?}',['as' => 'search','uses' => 'SearchController@search']);

I want to be able to define this in /vendor/author/package/src/Http/routes.php:

Route::get('/search/properties', ['as' => 'properties','uses' => 'PropertyController@search']);

The app/Http/routes.php file is loaded first so the route in their is used, not the package.

In Laravel 4 I would do this using App::before or App::after, giving them a priority.

Like so in the package routes:

App::before(function() {
    Route::get('/search/properties', ['as' => 'properties','uses' => 'PropertyController@search']);
});

I don't know how to achieve this in Laravel 5. I found this https://mattstauffer.co/blog/laravel-5.0-middleware-filter-style, but don't know how to use that to do what I want.

Edit: The Laravel 4 way of doing this would allow this priority to be set per route, so I'm not just loading all of the package routes before the app.

like image 715
Harry Potts Avatar asked Mar 03 '15 12:03

Harry Potts


People also ask

How do you use middleware on a route?

Assigning Middleware To Routes If you would like to assign middleware to specific routes, you should first assign the middleware a key in your application's app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel.

What's a main purpose of middleware in Laravel?

Laravel Middleware acts as a bridge between a request and a reaction. It is a type of sifting component. Laravel incorporates a middleware that confirms whether or not the client of the application is verified. If the client is confirmed, it diverts to the home page otherwise, it diverts to the login page.

What does the terminable middleware run in Laravel?

Terminable middleware performs some task after the response has been sent to the browser. This can be accomplished by creating a middleware with terminate method in the middleware. Terminable middleware should be registered with global middleware. The terminate method will receive two arguments $request and $response.

Can we apply middleware on controller?

We can also assign the middleware to the controller's routes within your route files. There are various ways of assigning the middleware to the controller: Assigning the middleware to the controller in the web.


1 Answers

You should be able to change the order in which routes are registered by changing the order of service providers in config/app.php.

Currently it probably looks somewhat like this:

'providers' => [
    // ...
    'App\Providers\RouteServiceProvider',
    // ...
    'Vendor\Package\PackageServiceProvider',
],

Now just change the order so the package is loaded first:

'providers' => [
    // ...
    'Vendor\Package\PackageServiceProvider',  // register package routes first
    'App\Providers\RouteServiceProvider',
    // ...
],

To just prioritize specific routes you can (ab)use the service providers register() method. I don't really like method but it works and I couldn't find anything better...

When the service providers are loaded the register() method of every provider is called. After that (and in the same order) the boot() method. That means independent of the order of your providers the register() method in your package will always be called before the boot() method in the RouteServiceProvider. This could look somewhat like this:

class PackageServiceProvider extends ServiceProvider {
    public function boot(){
        // register the regular package routes
    }

    public function register(){
        // register route "overrides"
        // for example like this: (obviously you could also load a file)
        app('router')->get('/search/properties', ['as' => 'properties','uses' => 'PropertyController@search']);
    }
}
like image 139
lukasgeiter Avatar answered Sep 30 '22 03:09

lukasgeiter