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

Is it possible to map different resources to the same model #610

Open michaelklopf opened 3 years ago

michaelklopf commented 3 years ago

Hi,

I'm currently trying to resolve an issue I have with how the API is structured. We have two different kind of users that are appearing in relationships. I'm looking for a way to differentiate the two user groups with resources. Something like this

'resources' => [
    'employees' => \App\User::class,
    'consultants' => \App\User::class,
]
$api->resource('assignments')
  ->only('index', 'read', 'update')
  ->relationships(function ($relations) {
      $relations->hasOne('created-by', 'employees')->readOnly();
      $relations->hasOne('supported-by', 'consultants');
  }) //...

When querying the relationship /api/assignments/1/created-by I would like to receive the underlying user object as "type": "employees" and for /api/assignments/1/supported-by as "type": "consultants".

Employees and consultants have their own schemas and adapters, but for both resources I'm getting "type": "employees".

Is there a solution in this package, or do I need to make a new model class for the different user types?

ben221199 commented 3 years ago

In that case I think you should make a base class User that will be extended by Employee and Consultant. For both models you will make the necessary classes, like Schema, Verification, Adapter, etc.

zlodes commented 3 years ago

Another {json:api} implementation for Laravel has ability to do it.

Docs: https://laraveljsonapi.io/docs/1.0/digging-deeper/proxies.html

Repo: https://github.com/laravel-json-api/laravel.

It's developed by author of this package and has a lot of new cool features and improvements. I suggest you to use the brand new package.

lindyhopchris commented 3 years ago

@michaelklopf the underlying encoder uses the class of the model to determine how to encode it - so it will not be able to distinguish between employees and consultants if you're using the same User model class for both.

You'd need to use a separate model class for both - as @ben221199 suggests, having a User model class that is extended by an Employee and Consultant is a good way to go - they can of course both read from the same database table if that's how your setup works.

Otherwise you need some sort of proxy implementation. I've implemented that for the next generation of this package - which is the laravel-json-api/laravel package that @zlodes has mentioned. If you'd prefer to use that proxy implementation, you'd need to switch to using that package. It's currently on beta releases but is usable in production if you don't mind the odd breaking change before I hit 1.0.0-rc.1.

michaelklopf commented 3 years ago

Thank you guys. I still have to look at the new version and find out how migration would work out. And thanks for bringing in the alternative solutions.