Creating multiple route files to drop in Posted on June 27, 2016

Sometimes when working on a big project I wish there was a way to have multiple route files for the project so that things can be simplified and kept simple. Luckily Laravel allows us to do this and I have already written about it

However, I wanted to take it one step further in an application that I was working on and allow Laravel to look for new Routes file and if it finds them then load them up. Basically creating a Drop in system using routes.

With this approach I am able to create a single or multiple route files for a module/application and just drop them into my Routes folder and Laravel will automatically see that. So no longer editing the routes themselves then heading over to routes.php to edit that file also.

Let's take a look at how we can accomplish such a thing.

The folder structure

First let's tackle the folder structure that I am implementing. This structure might not fit your needs but you can definitely change this easily. I create a folder called Routes inside my app/Http folder. So in the end I would have something looking like the following

  • app
    • Http
      • Routes

The code I am using will allow me to either drop a file in my Routes folder or drop another folder inside of it.

Route Service Provider

Laravel comes with it's own Route Service Provider and it is in charge of applying namespacing, middleware, etc. You can either create your own Service Provider or add on to this service provider, I will leave that up to you to decide. For this example I will just be editing the Route Service Provider itself.

Inside the service provider you will find a function called map

public function map(Router $router)
{
    $this->mapWebRoutes($router);
}

This is pretty simple and just calls another function. I will be changing it to also call our new function which we will take a look at in a second.

public function map(Router $router)
{
    // where our route folder is located
    $path = app_path('Http/Routes');
    $this->mapWebRoutes($router);

    // load our custom routes
    $this->mapApplicationRoutes($router, $path);
}

So I have added a variable that you could store in the class itself, and I have also added a function call to mapApplicationRoutes. This new function will be in charge of going through our directory and finding any files and applying them to the router itself. Basically appending the routes on.

The function will need to grab all the files and folders within the current directory that it is in. It will need to then check to see if the object is a file or a folder. If it is a file then it can easily include it. If it isn't a file then we want to traverse into that directory and perform the same actions.

Let's take a look at the finish code

<?php

protected function mapApplicationRoutes(Router $router, $currentDirectory)
{
    // grab all files and folders for the current directory
    // removing the . and double .. from our array for us automatically
    $directoryStructure = array_diff(scandir($currentDirectory), array('..', '.'));

    // for each of the items in our structure
    foreach($directoryStructure as $structureObject) {
        // configure the full path (eg: /var/www/html/example/app/Http/Routes/file.php)
        $fileOrFolderObject = $currentDirectory . '/'. $structureObject;

        // check to see if the fileOrFolderObject is a file or a folder
        if(is_file($fileOrFolderObject)) {
            // this is a file so we can import this into the router
            $router->group([
                'namespace' => $this->namespace, 'middleware' => 'web',
            ], function ($router) use ($fileOrFolderObject) {
                require $fileOrFolderObject;
            });
        } else {
            // we have a folder in this case
            // we can call ourselfs with our current path so that it will
            // perform all of the same checks as we just did but for the new folder
            $this->mapApplicationRoutes($router, $fileOrFolderObject);
        }
    }
}

Conclusion

Well I hope the provider is self explanatory. It basically will recursively go into the sub directories and for every file that it finds it will try to require it and put it into the router.

Share this post