dingo / api

A RESTful API package for the Laravel and Lumen frameworks.
BSD 3-Clause "New" or "Revised" License
9.33k stars 1.25k forks source link

"Register A Transformer For A Class" does not work #1657

Closed manyeung closed 5 years ago

manyeung commented 5 years ago

I am following the wiki to use the transformer but it does not work after update the framework from Laravel 5.4 to 5.5+.

$this->response->paginator(), $this->response->item() and $this->response->collection() works fine but app('Dingo\Api\Transformer\Factory')->register() does not work.

Q A
Bug? yes
New Feature? no
Framework Laravel
Framework version 5.5.*, 5.6.*, 5.7.*, 5.8.*
Package version 2.*
PHP version 7.1.29

Actual Behaviour

{
    "current_page": 1,
    "data": [
        ...
    ],
    "from": 1,
    "last_page": 4,
    "next_page_url": "http://localhost/api/users?page=2",
    "path": "http://localhost/api/users",
    "per_page": 15,
    "prev_page_url": null,
    "to": 15,
    "total": 50
}

Expected Behaviour

{
    "data": [
        ...
    ],
    "meta": {
        "pagination": {
            "total": 50,
            "count": 15,
            "per_page": 15,
            "current_page": 1,
            "total_pages": 4,
            "links": {
                "next": "http://localhost/api/users?page=2"
            }
        }
    }
}

Steps to Reproduce

routes/api.php:

$api->version('v1', function ($api) {
    $api->get('users', 'App\Http\Controllers\UserController@index');
});

UserController.php:

public function index()
    {
       // NOT WORK
        app('Dingo\Api\Transformer\Factory')->register(User::class, new UserTransformer);
        return User::paginate();

        // WORK
        // return $this->response->paginator(User::paginate(), new UserTransformer);
    }

UserTransformer.php:

class UserTransformer extends TransformerAbstract
{
    public function transform(User $user)
    {
        return [];
    }
}
specialtactics commented 5 years ago

To be honest, I've never used the transformers in that way, I use the other methods you've mentioned.

I recommend not using the transformer factory, the whole routing aspect of Dingo needs a good re-write, so IMO it's not worth spending time looking at this.

If you want to have a look and submit a PR, I'll be happy to review it though :)

specialtactics commented 5 years ago

I've looked into it, basically User::paginate() will just return a LengthAwarePaginator instance, and Dingo will not know what to do with it - you need to use dingo's response functions (like in your example that works).

I am not sure what the problem is to be honest.

manyeung commented 5 years ago

@specialtactics According to the wiki, it has mentioned below:

// When you register a transformer for a given class you'll be able to return the class (assuming it can be turned into an array) directly from your routes and it'll be run through the transformer automatically. This is great for simple APIs where you're using models as you can simply return the model from your route. //

Do you mean that the app('Dingo\Api\Transformer\Factory')->register('User', 'UserTransformer'); only works for Model but not for Eloquent\Collection and LengthAwarePaginator?

specialtactics commented 4 years ago

@manyeung Yes, maybe the paginator more so than collection - but I didn't test that distinction.