irclever's avatar

Namespaces and Routing

Hi all, having a tough time here with namespaces in routes.

When I apply the namespace directly to the class it works as expected (loads the content from index() in DashboardController):

Route::middleware(['auth', 'can:access shp'])->name('shp.')->prefix('shp')->group(function () {
    Route::get('/', [App\Http\Controllers\SHP\DashboardController::class, 'index'])->name('dashboard');
});

When I mess up the namespace it fails as expected with binding resolution error:

Route::middleware(['auth', 'can:access shp'])->name('shp.')->prefix('shp')->group(function () {
    Route::get('/', [App\Http\Controllers\SHPZZZZZ\DashboardController::class, 'index'])->name('dashboard');
});
Target class [App\Http\Controllers\SHPZZZZZ\DashboardController] does not exist.

Using namespace() I get same binding resolution error but the namespace is absent:

Route::middleware(['auth', 'can:access shp'])->name('shp.')->prefix('shp')->namespace('App\Http\Controllers\SHP')->group(function () {
    Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
});
Target class [DashboardController] does not exist.

UPDATE: by chance I figured out the namespace is only prepended to Route::resource() routes but not to normal routes.

//namespace works:
Route::resource('studios', StudioController::class);

//namespace ignored and produces target class [StudioController] doesn't exist error:
Route::get('studios', [StudioController::class, 'index'])->name('studios.index');

I'm using Laravel 10 and the docs barely mention namespaces in the routing section and there's no mention of the Route::resource (only the old Route::controller) group.

So is it safe to to say namespaces and resource groups in routing are a thing of the past and v10^ best practice is to import every class and write out every controller method?

Or am I missing something?

0 likes
4 replies
alden8's avatar

@irclever

-- namespaces are not a thing of the past. They remain crucial for organizing code, preventing naming conflicts, and promoting modularity. Use Route::namespace() to apply namespaces to route groups, avoiding repetitive full class paths

-- while Route::resource() isn't explicitly mentioned in the Laravel 10 docs, it's still functional and respects namespaces. It automatically prepends the namespace from the route group to the controller class

-- for normal routes (not resource routes), you'll need to specify the full class name with its namespace. This ensures the controller is correctly resolved

-- Group related controllers within namespaces based on functionality or features. Apply Route::namespace() to groups of routes sharing the same namespace. Include the namespace for clarity and to avoid potential errors. If using IDE auto-completion or avoiding manual namespace repetition, import classes using use statements. For extensive routes, explore packages like laravel-controllers for automatic route registration based on conventions

Route::middleware(['auth', 'can:access shp'])->name('shp.')->prefix('shp')->namespace('App\Http\Controllers\SHP')->group(function () {
    Route::get('/', 'DashboardController@index')->name('dashboard'); 
});
1 like
irclever's avatar

@alden8

Thank you very much for your reply, it helped me find a solution:

Route::namespace('App\Http\Controllers\SHP')->group(function () { 
  Route::get('/str', 'DashboardController@index'); //200
  Route::get('/arr', [DashboardController::class, 'index']); //500 Target class [DashboardController] does not exist BindingResolutionException
});

Now I don't have to add 80+ controllers to my routes files. First time the legendary documentation has let me down after many years. Does this warrant a PR on GitHub? At least for the docs if not the core?

2 likes

Please or to participate in this conversation.