cloudcreativity / laravel-json-api

JSON API (jsonapi.org) package for Laravel applications.
http://laravel-json-api.readthedocs.io/en/latest/
Apache License 2.0
778 stars 109 forks source link

Extending and registering controller with custom action: Target class [OrdersController] does not exist #607

Closed ranferi closed 3 years ago

ranferi commented 3 years ago

Hi. I'm trying to extend a controller for my 'orders' resource to add a new action 'completed'. But when I added the method controller() to the route and I run php artisan route:list, it send this error (I'm using laravel-json-api version 3.2.0):

Target class [OrdersController] does not exist

this is my configuration in api.php:

JsonApi::register('v1')->routes(function ($api) {
$api->resource('orders')
        ->relationships(function ($relations) {
            $relations->hasOne('seller');
            $relations->hasMany('products');
        })->controller()->routes(function ($orders) {
            $orders->get('{record}/completed', 'completed');
        });
}

But if I added the controller like this, it works

// this works!!!!
->controller('App\Http\Controllers\OrdersController')->routes(function ($orders) {
            $orders->get('{record}/completed', 'completed');
        })

My configuration in my json-api-v1.php it's not that different from the default file (i think a set 'url' to adapt to my api route):

'url' => [
        'host' => null,
        'namespace' => '/api/v1',
        'name' => 'api.v1.',
    ],
'controllers' => [
        'transactions' => true,
        'connection' => null,
    ],
// more config here

and my controller looks like this:

namespace App\Http\Controllers;

use App\Models\Orders\Order;
use CloudCreativity\LaravelJsonApi\Http\Controllers\JsonApiController;
use Illuminate\Http\Response;

class OrdersController extends JsonApiController
{
    public function completed(Order $order): Response
    {
        return $this->reply()->content($order);
    }
}

Another thing I tried, before using the complete path to the controllers, was to change the controller to another namespace ('Api', 'api', 'Api\V1') and didn't work.

It's there something I'm missing in my config that causes this problem of the missing controller?

lindyhopchris commented 3 years ago

This due to a change in Laravel.

A freshly installed Laravel 8 application now no longer uses controller namespacing - the $namespace property on the RouteServiceProvider is not set. This means when referencing controllers when defining routes, you need to fully qualify the controller class name.

In this scenario, this is therefore correct:

->controller(\App\Http\Controllers\OrdersController::class)->routes(function ($orders) {
        $orders->get('{record}/completed', 'completed');
    })
ranferi commented 3 years ago

@lindyhopchris again, thank you!!