fractal
fractal copied to clipboard
JsonApiSerializer doesnt conform the specs for fetching relationship urls
i think this needs a whole resource type tbh but im sure they may be other ways too.
take this example:
/api/users/1?include=user_meta
This works great, and the data is formatted as expected.
however as per the spec each included/related resource has its own links which MUST be satisfyable as per the spec at:
/api/users/1/user_meta /api/users/1/relationships/user_meta
The serializer does an amazing job of generating those links and requires nothing on our end to complete (which made me drool the first time i used it).
no lets satisfy either of those urls:
/api/users/1/user_meta
in my code, i have something like this:
//$meta is a collection of models (laravel)
$meta = functiontofetchusermetabyid($id);
return Fractal\Resource\Collection($meta, UserMetaTransformer::class, $this->type);
this will return something like this:
{
"data":[
{
"type":"user_meta",
"id":"1",
"attributes":[..the atts...],
"links":{
"self":"\/api\/user_meta\/1"
}
}
]
}
however this isnt what the spec says, it should look like this:
{
"links": {
"self": "/users/1/relationships/user_meta",
"related": "/users/1/user_meta"
},
"data": [
{ "type": "user_meta", "id": "1" },
{ "type": "user_meta", "id": "2" }
]
}
There are a few issues here:
- it should have a top level links object
- resource objects shouldnt have any attributes
- resource objects shouldnt have a links object
Ive reread the docs a few times, and its not right:
A "resource identifier object" MUST contain type and id members.
A "resource identifier object" MAY also include a meta member, whose value is a meta object that contains non-standard meta-information.
there are other places in the docs that it also mentions nothing about including resources for these requests at all, so basically the response should only contain:
- a data object with nested resource objects
- a links object containing the current link and related link.
Im currently having to prepare a custom response and not use fractal for this, but it would be great if it was possible.
Todo so i propose the addition of a new resource type, currently there are:
- null resource
- item resource
- collection resource
The new resource type should be a relationship resource
I think this would be need to implemented as a resource class, in the scope class, and then within the serializers as well, but looking at it, it doesnt look overly hard to implement.
Then we could all use:
$resource = new Fractal\Resource\Relationship($books, new BookTransformer, 'books');
which would format the data as expected.
Im happy to have a go at making a pull request for this if you agree this is a needed addition.
just a few more notes:
the transformer used could be any existing or new transformer, but in reality all it needs to do is return either an item resource with an id, or a collection resource with an id.
Any other data returned would just be ignored.
optimally a transformer which only proccessed the item by returning its id would be favourable, but re-using an existing transformer for the item would (shouldnt) break anything as all we need is the id key returned in the array.
We could enforce this via interfaces, but even though its favourable to have a different transformer for optimisation this should be left down the end user.
I agree completely with this, I'm adding it to my todo list right now
@willishq Oh, yes. There are critical troubles with relationships :(
- I simply can't include ONLY relationships links into object. For example, I have countries and cities, I don't want to include thousands of cities in country payload, but I should include a top-level relationships field with links to nested city resources (e.g. /countries/1/cities). Now there is no possibility for that
- Even when base url for serializer is provided and relations are included, relation does not contain links:
data: [
{
type: "countries",
id: "19",
attributes: {
name: "Австралия",
currency_code: "AUD",
currency: "Австралийский доллар"
},
links: {
self: "http://desk.nalivator.app/countries/19"
},
relationships: {
cities: {
data: [
{
type: "cities",
id: "3979034"
}
]
}
}
}
],
included: [
This makes almost impossible to work with relationships with spec-fullfilling clients (like ember.js for example)
Is there any update on this? I am attempting to implement an API following the JSON-API spec and have hit this road block with Fractal.
Same here, would be very interested in knowing how this is getting along. @willishq?
Any news on this?
I'm also interested about any news on this?
At the risk of necro-ing an old issue, i'm guessing that since this issue is 3 years old now that this is a dead issue?
At this point I believe it won't happen, sadly.
Any updates?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 4 weeks if no further activity occurs. Thank you for your contributions.