DEV Community

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

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)