JsonApiSerializer - how to create top level links object automatically
I am currently getting the output of the JsonApiSerializer like that:
{
"data": {
"type": "companies",
"id": "c1e5d2eb-bf0c-4b4b-97c8-d594be334e62",
"attributes": {
"name": "Jane Doe GmbH",
"street": "South Street 20",
"zip": "90000",
"city": "Sunshine",
"country": "USA",
"description": "Personal Trainer",
"email": "[email protected]",
"tel": "123456763",
"tel_code": "0043",
"url": "jane-doe-gmbh",
"created_at": "2015-08-05T08:40:51.620Z"
},
"links": {
"self": "/companies/c1e5d2eb-bf0c-4b4b-97c8-d594be334e62"
},
}
}
But I would like to "move up" the links object that is generated by JsonApiSerializer to the top-level of the Response or to have a duplicate of it at the top level (as in this JsonApi Specification example)
{
"links": {
"self": "/companies/c1e5d2eb-bf0c-4b4b-97c8-d594be334e62"
},
"data": {
"type": "companies",
"id": "c1e5d2eb-bf0c-4b4b-97c8-d594be334e62",
"attributes": {
"name": "Jane Doe GmbH",
"street": "South Street 20",
"zip": "90000",
"city": "Sunshine",
"country": "USA",
"description": "Personal Trainer",
"email": "[email protected]",
"tel": "123456763",
"tel_code": "0043",
"url": "jane-doe-gmbh",
"created_at": "2015-08-05T08:40:51.620Z"
}
}
}
Is this possible somehow, or do I have to "extend" JsonApiSerializer to get this functionality?
Why would you want that?
~~Both of your outputs are equal when being accessed as JS Object. In other words: If the order of keys makes a difference for you, either you or the library you are using, is parsing JSON wrong~~
Edit:\
Forget about the above. The current implementation still matches the specification as one item of a collection links to exactly himself and the top-link only references where you currently are (the link of the collection itself). In cases where you fetch one particular item, they happen to be the same. But, the link-item itself is not a requirement.
The api states 'Where specified, a links member can be used to represent links. The value of each links member MUST be an object (a "links object").'
Why would you want that?
I would like our API to respect the JsonApi spec. As you can see there is a small but notable difference between the examples.
In the first example the links object is a child of data, in the second example it's a top level node.
Correct me if I am wrong, but as to my understanding of the JsonApi spec it should be possible to put it to both positions:
{
"links": {
"self": "/companies/c1e5d2eb-bf0c-4b4b-97c8-d594be334e62"
},
"data": {
"type": "companies",
"id": "c1e5d2eb-bf0c-4b4b-97c8-d594be334e62",
"attributes": {
"name": "Jane Doe GmbH",
"street": "South Street 20",
"zip": "90000",
"city": "Sunshine",
"country": "USA",
"description": "Personal Trainer",
"email": "[email protected]",
"tel": "123456763",
"tel_code": "0043",
"url": "jane-doe-gmbh",
"created_at": "2015-08-05T08:40:51.620Z"
},
"links": {
"self": "/companies/c1e5d2eb-bf0c-4b4b-97c8-d594be334e62"
}
}
}
I think this is not possible at the moment. Also you can't include the jsonapi and errors properties in the document root atm.
@Art4: thanks for letting me know. I am now investigating https://github.com/neomerx/json-api for this purpose, but would love to use Fractal for it because of it's elegance and simplicity.
but you could use meta key for other info but data
@Perni1984 @Suven: A correct output according to the JSON API specs would be the following:
{
"links": {
"self": "/companies",
"next": "/companies?page[offset]=2",
"last": "/companies?page[offset]=10"
},
"data": {
"type": "companies",
"id": "c1e5d2eb-bf0c-4b4b-97c8-d594be334e62",
"attributes": {
"name": "Jane Doe GmbH",
"street": "South Street 20",
"zip": "90000",
"city": "Sunshine",
"country": "USA",
"description": "Personal Trainer",
"email": "[email protected]",
"tel": "123456763",
"tel_code": "0043",
"url": "jane-doe-gmbh",
"created_at": "2015-08-05T08:40:51.620Z"
},
"links": {
"self": "/companies/c1e5d2eb-bf0c-4b4b-97c8-d594be334e62"
}
}
}
The top level section is reserved for the document's primary data (i.e. links to the current API), and the link section within each "data" section is reserved for the resource object(s).
All this can be found clearly explained in the JSON API specs; http://jsonapi.org/format/#document-top-level
Cheers
~~@jonaholsson, @Suven : You are correct. Thanks for clearing this up. I misread the spec.~~
edited: see comment below.
@jonaholsson Sorry if I'm wrong, but the resource /companies looks like a collection so the data attribute must be an array with the object inside:
{
"links": {
"self": "/companies",
"next": "/companies?page[offset]=2",
"last": "/companies?page[offset]=10"
},
"data": [{
"type": "companies",
"id": "c1e5d2eb-bf0c-4b4b-97c8-d594be334e62",
"attributes": {
"name": "Jane Doe GmbH",
"street": "South Street 20",
"zip": "90000",
"city": "Sunshine",
"country": "USA",
"description": "Personal Trainer",
"email": "[email protected]",
"tel": "123456763",
"tel_code": "0043",
"url": "jane-doe-gmbh",
"created_at": "2015-08-05T08:40:51.620Z"
},
"links": {
"self": "/companies/c1e5d2eb-bf0c-4b4b-97c8-d594be334e62"
}
}]
}
@jonaholsson, @Suven, @Art4: I just looked up the examples in the spec again, but I have to revise my statement from before. My case was about getting an individual company resource.
The example given in the spec looks like that:
For example, a GET request to an individual article could return:
HTTP/1.1 200 OK Content-Type: application/vnd.api+json{ "links": { "self": "http://example.com/articles/1" }, "data": { "type": "articles", "id": "1", "attributes": { "title": "JSON API paints my bikeshed!" }, "relationships": { "author": { "links": { "related": "http://example.com/articles/1/author" } } } } }
So in reality the self link can move up to the top level (or the example in the spec is wrong), so my first question was valid.
@Perni1984 @Art4 Yes, it seems you're both correct! I was a bit quick on my reply. Now I'm looking forward to such an implementation in Fractal too (+ jsonapi and errors properties as mentioned earlier in this topic) :)
@Perni1984 are you still using Fractal for JSON-API or have you moved to neomerx? I would like to use fractal, but it seems like neomerx is further along.
@hglattergotz: in the end we used Neomerx for that particual project.
@Perni1984 Thanks
Its 2020 and we still cannot create top level errors field?
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.