DEV Community

Cover image for Modularising Routes for Scalability and Clarity
Nasrul Hazim
Nasrul Hazim

Posted on

Modularising Routes for Scalability and Clarity

Managing route definitions in a large Laravel application can quickly become overwhelming—especially when dealing with complex modules like admissions, academics, and user management.

To ensure long-term maintainability, I recently refactored our admin route setup into a well-structured and modular format.

In this post, I’ll share how we transitioned from a monolithic route group to a fully modular setup and what benefits it brings.


🚧 The Challenge: Growing Route Complexity

Initially, all admin-related routes were grouped inside a massive closure in web.php. This approach worked fine at first, but as the system evolved:

  • The route file grew to hundreds of lines.
  • Unrelated concerns (e.g., admission vs programme) were tangled together.
  • Collaboration became error-prone due to constant merge conflicts.

We needed a better structure.


🧭 The Strategy: Structured Route Definitions

Instead of stuffing everything into web.php, we organised our routes into dedicated files under a routes/web/admin directory.

✅ Step 1: Central Admin Route Loader

// routes/web/admin.php

use Illuminate\Support\Facades\Route;

Route::group([
    'middleware' => ['is_admin', 'auth', 'verified'],
    'prefix' => 'admin', 'as' => 'admin.',
], function () {
    require_all_in(base_path('routes/web/admin/*.php'));
});
Enter fullscreen mode Exit fullscreen mode

This loads all files matching admin/*.php, keeping the main file clean.

✅ Step 2: Nested Setup Group

Setup-related routes are more detailed, so we pushed them further into a subdirectory:

// routes/web/admin/setup.php

use Illuminate\Support\Facades\Route;

Route::group(['prefix' => 'setup', 'as' => 'setups.'], function () {
    require_all_in(base_path('routes/web/admin/setup/*.php'));
});
Enter fullscreen mode Exit fullscreen mode

This allows better organisation and logical grouping of setup domains like CRM, programme, admission, etc.


📁 Final Directory Layout

routes/
└── web/
    ├── admin.php                  # Loads all admin route groups
    └── admin/
        ├── academics.php
        ├── admissions.php
        ├── prospective-student.php
        ├── users.php
        ├── impersonate.php
        ├── governance.php
        ├── excel.php
        ├── profile.php
        ├── misc.php
        ├── document-template.php
        ├── letter.php
        ├── setup.php             # Loads all setup submodules
        └── setup/
            ├── admission.php
            ├── crm.php
            ├── programme.php
            ├── residential.php
            ├── student-record.php
            └── common.php
Enter fullscreen mode Exit fullscreen mode

🔍 Verifying the Structure

After restructuring, I dumped the route list before and after, then compared them programmatically.

Outcome:

  • ✅ No routes were removed.
  • ✅ No duplication or misrouting occurred.
  • ✅ Route paths, names, and middleware stacks stayed intact.

🛠 Bonus

Dump routes before and after refactor

You may wan to dump the before refactor routes and after refactor the routes:

php artisan route:list --json > routes/route-ori.json
Enter fullscreen mode Exit fullscreen mode

Then after refactor:

php artisan route:list --json > routes/route-refactor.json
Enter fullscreen mode Exit fullscreen mode

Grab those two JSON files, and dump to ChatGPT / Claude to help you analyse and compare differences in both route files.

If there's missing routes, you may double check and add back those missing routes.

The require_all_in() Helper

To autoload all files in a directory, I used this helper:

function require_all_in($path) {
    foreach (glob($path) as $filename) {
        require_once $filename;
    }
}
Enter fullscreen mode Exit fullscreen mode

This keeps each route group isolated and ensures automatic loading without manual imports.


🚀 Why This Matters

This restructuring significantly improved:

  • Readability: Route responsibilities are clearly separated.
  • Modularity: Easy to locate and modify specific feature routes.
  • Team Collaboration: Developers can work independently in their modules.
  • Future Growth: Adding new route groups doesn’t clutter core files.

🏁 Conclusion

A well-structured route directory makes a huge difference in large Laravel applications. If you're managing more than a few modules, modularising and grouping your routes should be a standard practice.

It’s a small change with massive long-term impact.

Top comments (0)