Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

alariva's avatar

Is it possible to prioritize a package's routes?

This is the scenario: I have the application routes, and I'm extracting the backend as a package, so it now has it's own routes.

But the application currently handles -say, to simplify- 3 types of routes:

  • Application routes, run first
  • Backend routes, run after
  • Application catch everything, run last

So currently, since I got the Backend split, It's routes are registered last like follows:

  • Application routes, run first
  • Application catch everything, run last
  • Backend routes, run after

If you ask for actual code this is my route files pointing to the ROOT CONTEXT I want to extract. Note that once in the package's routes it is registered last and thus the priority lost.

Thanks!

0 likes
7 replies
TerrePorter's avatar

@alariva Your problem is that the order of load is app, then packages. So everything in the main app will load before any of the packages.

I'm assuming the "Application catch everything, run last" is the end route in the route file - https://github.com/alariva/timegrid/blob/master/app/Http/routes.php#L389

Perhaps, you can make a package and have the service provider load that one route, but have it load after the backend.

So in the app/config it would be something like:

// app\config.php

 'providers' => [
        ...       
        Alariva\Tidiochat\TidioChatServiceProvider::class,
// load backend service provider (or where ever)
// load catch all service provider (last in the providers array)
    ],

So you have ... Base App Service Providers... (Main app routes load) BackendServiceProvider.php...(Backend route loads) CatchAllRouteServiceProvider.php... (the catch all route loads)

I know it sounds odd to have a package just for the catchall, but I think you can control when the route loads that way.

1 like
alariva's avatar

@TerrePorter , thank you for the approach, seems to make sense.

So far I came up with 4 different approaches:

  • Forcing priority through a third party package would help but I found it overkill for my case and adding the need to forcedly (vs naturally) maintain priorities.

  • Using regex to skip a catch all group. This was not possible since ->when() cannot be used after ->group()

  • Prefixing a catchall and using regex to skip the backend (or a set) prefix when catching all. This is, I catch all but skip those prefixes starting with _ so as I can use them for system functions. This is the approach I took so far and it's working on this branch with this extracted package, but still there is something making noise to me; the App must allow a routing path to get resolved to the backend. Sounds more natural that backend route is processed first with no chance to the app to try to catch such important path.

  • Extracting Frontend into a package so it runs after the Backend package. Similar to the solution you told, and makes sense since it would hold all the entire frontend logic with the last catch all declaration.

alariva's avatar

Another apparent solution I found is loading the package service provider before my application route service provider, like so:

        // ...

        Timegridio\Backend\TimegridioBackendServiceProvider::class,

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\ComposerServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

        // ...

instead of

        // ...

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\ComposerServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

        // ...

        Timegridio\Backend\TimegridioBackendServiceProvider::class,

        // ...

It is working and my tests passing, any caveats on this??

TerrePorter's avatar
Level 12

@alariva Looks like you have consider a lot of things.

The third-party package would allow a more specific route order, but would also tie both the front and backend to a prioritization package. I can see that it would work, but personally I'm not in favor of it.

The third thought does present the problem you describe, the app's catch-all route could cause package routes to be skipped.

I like the last option (but i'm slightly bias), a separate frontend and backend, as packages, this would allow you to control the load order of the routes and keep the catch-all with its real package. Only thing to make sure is that the backend does not rely on any data (settings, etc) from the frontend as the backend would be loading first and those config values would not be present.

I working on something similar on a project currently. I have a core module, a display module, and a admin module (plus a few others) - my only difference is there is no catch all route in the routes.php, all pages route to the master loader function so it handles if routes exists or not. The admin was getting to be to much to be included with the main app, so i am extracting it to a separate project. But the premise is there, the core routes must load before the display routes, and in my case there are config values that are set which the display module must have that are set in the core module.

1 like
infernobass7's avatar

Hey I am not sure if you are still running into this issue. I ran into something similar but mine issue was with another third-party package and with Laravel's package Auto-discover feature, I wanted to find another way.

You can hook into the application after it has finished booting other providers, using the following function.

App::booted(function() {
        app('router')->get('{any}', 'Controller@method')->middleware('web')->where('any', '^.*$');
});
2 likes

Please or to participate in this conversation.