-1

I have this piece of routing here:

<?php

use App\Http\Controllers\SurveyController;

Route::middleware(['auth:api'])->controller(SurveyController::class)->group(function ($route) {
    $route->prefix('survey')->group(function ($route) {
        $route->post('show', ['show'])->name('survey_show');
        $route->post('answer', ['answer'])->name('survey_answer');
    });
    $route->prefix('member/survey')->group(function ($route) {
        $route->post('list', ['list'])->name('member_survey_list');
    });
});

The problem is that the route is unable to "find" the controller, I've tried many different approaches to this issue, I found a lot of info about this issue, but none of them could help me solve the problem, and either I get a "Function () does not exist" or a "Target class [App\\Http\\Controllers\\App\\Http\\Controllers\\SurveyController] does not exist.". I didn't want to declare the controller on each route as $route->request('path', [Controller::class, 'function']) since it will have an impact in future maintenance as the routes number grows bigger.

Am I using the method Route::controller()? Should I just write the controller on each route?

I'm using Laravel 8.83.5 and php 8.1.13.

UPDATED

my SurveyController

<?php

namespace App\Http\Controllers;

use App\Http\Resources\SurveyResource;
use App\Services\SurveyService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Exception;

class SurveyController extends Controller
{
    private SurveyService $service;

    public function __construct(SurveyService $surveyService)
    {
        $this->service = $surveyService;
    }

    /**
     * php doc here
     */
    public function list(Request $request): array
    {
        $data = $request->only(['keys']);

        $validator = Validator::make(
            $data,
            [
                'keys' => 'string'
            ],
            $this->customMessages
        );

        if ($validator->fails()) {
            throw new Exception($validator->errors(), 1);
        }

        return SurveyResource::method(
            $this->service->method(
                $data['keys']
            )
        );
    }

    /**
     * php doc here
     */
    public function show(Request $request): array
    {
        $data = $request->only(['keys']);

        $validator = Validator::make(
            $data,
            [
                'keys' => 'string'
            ],
            $this->customMessages
        );

        if ($validator->fails()) {
            throw new Exception($validator->errors(), 2);
        }

        return SurveyResource::show(
            $this->service->show(
                $data['keys']
            )
        );
    }

    /**
     * php doc here
     */
    public function answer(Request $request): array
    {
        $data = $request->only(['keys']);

        $validator = Validator::make(
            $data,
            [
                'keys' => 'string'
            ],
            $this->customMessages
        );

        if ($validator->fails()) {
            throw new Exception($validator->errors(), 3);
        }

        return SurveyResource::answer(
            $this->service->answer(
                $data['keys']
            )
        );
    }
}

on routes, I've tried calling the route with the method controller() as the first, this way I get a "Function () does not exist" error, the same error pops up when I use it just before the group() method

Route::controller(SurveyController::class)->middleware(['auth:api'])->group(function ($route) {    
    $route->prefix('member/survey')->group(function ($route) {
        $route->post('list', ['list'])->name('member_survey_list');
    });
});

also tried calling the route with SurveyController's method without an array, this way I get an "Target class [App\\Http\\Controllers\\App\\Http\\Controllers\\SurveyController] does not exist." error

Route::controller(SurveyController::class)->middleware(['auth:api'])->group(function ($route) {    
    $route->prefix('member/survey')->group(function ($route) {
        $route->post('list', 'list')->name('member_survey_list');
    });
});

Also saw some old threads saying that using an array inside the group() method with a namespace key and the namespace value could help, so I tried, but got a "Array to string conversion" error

Route::middleware(['auth:api'])->group(['namespace' => 'App\Http\Controllers\SurveyController'],function ($route) {    
    $route->prefix('member/survey')->group(function ($route) {
        $route->post('list', 'list')->name('member_survey_list');
    });
});

SOLUTION

Following the solution given by @matiaslauriti, first you need to remove the declaration of the namespace in the route file (you can keep the declaration if you remove it from the RouteServiceProvider.php), then you can either call it as Route::controller(ControllerName::class) or literally as Route::controller('ControllerName'). Here's my working code:

<?php

Route::controller(SurveyController::class)->middleware(['auth:api'])->group(function ($route) {
    $route->prefix('survey')->group(function ($route) {
        $route->post('show', 'show')->name('survey_show');
        $route->post('answer', 'answer')->name('survey_answer');
    });
    $route->prefix('member/survey')->group(function ($route) {
        $route->post('list', 'list')->name('member_survey_list');
    });
});
  • If you check the docs, when using the `controller()` method, you don't pass the function as an array: https://laravel.com/docs/9.x/routing#route-group-controllers. So change your code to `$route->post('show', 'show')` instead of `$route->post('show', ['show'])` (and the other ones), and then it should work. (Sidenote, voted to close as a typo/syntax issue) – Tim Lewis Jan 20 '23 at 19:16
  • When I do that, I got `"Target class [long path here] does not exist."` I've tried putting an `@` (as `'@show'`) but the error is the same. – Gregory Farias Jan 20 '23 at 19:28
  • Which one? Does your `SurveyController` actually have that method? Do you have the correct namespace? Please [edit your question](https://stackoverflow.com/posts/75188446/edit) with updated details, i.e. the new Routes without arrays, your new error message, and your `SurveyController` class. Also don't use the `@` sign; that's old Laravel 5 syntax, like `SurveyController@show`, but that hasn't been used in a long time. – Tim Lewis Jan 20 '23 at 19:31
  • 2
    Can you provide the full error message, instead of redacting the long path? It's complaining about the class, not the function. – aynber Jan 20 '23 at 19:45
  • Odd, it's duplicating the namespace. You can try `php artisan route:clear` on your command line to see if that helps, as well as `composer dumpautoload`. – aynber Jan 20 '23 at 20:03
  • @aynber tried that but no success – Gregory Farias Jan 20 '23 at 20:12
  • Probably related to this: https://stackoverflow.com/questions/63807930/error-target-class-controller-does-not-exist-when-using-laravel-8. In Laravel 8, the Route/Controller logic changed a bit: https://laravel.com/docs/8.x/upgrade#routing. I was able to get your code to work as written without this duplication, so I suspect that is the reason (As @matiaslauriti correctly pointed out in their answer below) – Tim Lewis Jan 20 '23 at 20:29

1 Answers1

1

If you are getting App\\Http\\Controllers\\App\\Http\\Controllers\\SurveyController error, that means you only have to pass SurveyController literally:

Route::controller('SurveyController')->middleware(['auth:api'])->group(function ($route) {    
    $route->prefix('member/survey')->group(function ($route) {
        $route->post('list', ['list'])->name('member_survey_list');
    });
});

I would recommend to switch to the new routing system, delete $namespace like this file and from everywhere on that file.

Then, you can do controller(SurveyController::class)

matiaslauriti
  • 7,065
  • 4
  • 31
  • 43
  • that worked nicelly, this is what the code became at the end `Route::middleware(['auth:api'])->controller('SurveyController')->group(function ($route) { $route->prefix('member/survey')->group(function ($route) { $route->post('list', 'list')->name('member_survey_list'); }); });` thx – Gregory Farias Jan 20 '23 at 20:18
  • marked as correct. Also calling the method as `controller('SurveyController')` or as `controller(SurveyController::class)` get the same result, working as well. Many thx – Gregory Farias Jan 20 '23 at 20:36