Comments (13)
It's also perfectly valid to have attributes whose values are URLs; URL values are not restricted to being placed in the links
object.
{
"data": {
"id": "4",
"type": "movies",
"attributes": {
"imdb": "https://www.imdb.com/title/tt0133093/",
"title": "The Matrix"
}
}
}
from json-api.
@jelhan Could an extension allow any custom links, without specifying them explicitely?
An extension can define any member name within their namespace. The namespace prevents collisions between members defined by an extension and potential additions to the base specification later. Please have a look at rules for extensions section for details.
While your suggestion would be syntactically compliant, I think this breaks the idea of REST (HATEOAS). IMHO links should be discoverable by knowing the media type structure, not by the implicite knowledge of the semantics of the data.
I don't see how your attempt to define any custom link fits with the purpose of HATEOAS. It is not enough that a link is discoverable. A consumer also needs to understand the meaning of that link. This is why the JSON:API specification carefully defines the meaning of the links.
I don't see much difference between { data: { attributes: { "imdb": "https://www.imdb.com/title/tt0133093/" } }
and { data: { links: { "imdb": "https://www.imdb.com/title/tt0133093/" } }
in that perspective. It might be easier to discover for a consumer that the value is an URL in the second example. But in both cases a consumer needs additional information to understand what that URL is about.
Please note that presenting data in links
object would have similar drawbacks to using meta
. Most importantly creating and updating these information is not defined by the specification. Attributes and relationships are meant to model data. I would highly recommend to use them.
from json-api.
Using an extension to allow them feels like a big burden. Can't we use rules similar to query parameters? By only reserving a-z link names and allowing custom links if they use camelCame for example.
This is an interesting proposal. I feel we should discuss it with a broader perspective. Opened #1680 to do so.
from json-api.
Your interpretation of the specification is correct. If not stated explicitly implementations (and profiles) are not allowed to add additional members. This includes links
objects.
The names are reserved for potential further usage by the specification itself. If implementations would be allowed to define additional members, adding new members to the specification would be a breaking change.
However this does not prevent usage of custom links. Extensions are allowed to define additional members. Including additional members of the links
object.
from json-api.
Thx for the replies.
@jelhan Could an extension allow any custom links, without specifying them explicitely?
@freddrake While your suggestion would be syntactically compliant, I think this breaks the idea of REST (HATEOAS). IMHO links should be discoverable by knowing the media type structure, not by the implicite knowledge of the semantics of the data.
from json-api.
Please see #1019 and #1656 for previous discussions on this topic.
from json-api.
@jelhan thx for the pointers.
from json-api.
Within the spec, the relationships
structure is different compared with the links
structure in terms of allowed members. I mean within a relationships
object, every JSON key can be used as member, which makes total sense to me. So the following JSON is JSON:API compliant:
{
"data": {
"id": "4",
"type": "movies",
"attributes": {
"title": "The Matrix"
},
"relationships": {
"directors": {
"links": {
"related": "/directors/254"
}
}
}
}
}
@jelhan wrote:
I don't see how your attempt to define any custom link fits with the purpose of HATEOAS. It is not enough that a link is discoverable. A consumer also needs to understand the meaning of that link.
In the above example any client can figure out from the JSON:API structure that a movie has a relationship to another resource, and that the name of this relationship is directors
. But the client also has to know the semantics of a director when following the related link within the relationship and then doing something useful with the response.
BTW, the background of this issue is the following. Many hypermedia media types have the approach that the name of a link (relation) can be chosen by the providing service, e.g. HAL, HAL-FORMS, Siren ...
Often services use content negotiation to provide different formats.
Many (or even most) of the links in above formats could probably be transformed into valid JSON:API relationships, but some probably cannot, because in a JSON:API relationship the related link ALWAYS has to link to a related REST resource. So @freddrake 's suggestion would be a valid way to express those links in JSON:API.
For me, the JSON:API spec standalone is fine, because most service developers could follow the following practice:
- Use
relationships
to express relations between rest resources - When using
links
, stick to the allowed members - Use custom attribute names that can contain an URI value otherwise
But if you have a generic programming model that provides a link abstraction, and you want to provide different media types as output, it is a bit harder to make the result JSON:API compliant.
from json-api.
Within the spec, the
relationships
structure is different compared with thelinks
structure in terms of allowed members. I mean within arelationships
object, every JSON key can be used as member
Both have very different purpose in the specification.
The relationships object represents links between different resource. In combination with the attributes object it is responsible for representing the data. The data model of an API is highly domain driven. It can not be standardized in a generic way. Therefore the spec only puts few constraints on it, e.g. that a relationship must not have the same name as an attribute.
The links object provides a client information how to construct additional requests. E.g. a self
link of a JSON:API document provides a client all information needed to reload the document. A self
link of a resource object provides needed information to reload, update or delete a specific document. A related
link of a relationship object provides needed information to fetch the resource objects referenced by that relationship. Etc.
Further standardizing allowed members of a relationships object would very likely conflict with JSON:API's goal to be agnostic about the data model of an API. Less standardizing allowed members of a links object would prevent a client from use these links in a meaningful way.
But if you have a generic programming model that provides a link abstraction, and you want to provide different media types as output, it is a bit harder to make the result JSON:API compliant.
I would recommend to use an extension for these cases. An extension could not only define additional members but also define processing rules for them. Using an extension enables content negotiation.
from json-api.
BTW, the background of this issue is the following. Many hypermedia media types have the approach that the name of a link (relation) can be chosen by the providing service, e.g. HAL, HAL-FORMS, Siren ...
I'm not very familiar with all of them. But the _links
object in HAL seems to have conceptually more in common with the relationships object of JSON:API spec than with the links object. The intent of _links
in HAL is to expression relationships between resources. That's what the relationships object in JSON:API specification is about.
HAL does not seem to specify that a provided link must also return a HAL document. That seems to be the main difference compared to JSON:API specification.
from json-api.
I do see the value in custom resource links (I've actually used them for a long time, unaware of this limitation), for example for the html variant of the resource.
Using an extension to allow them feels like a big burden. Can't we use rules similar to query parameters? By only reserving a-z link names and allowing custom links if they use camelCame for example.
from json-api.
I do see the value in custom resource links (I've actually used them for a long time, unaware of this limitation), for example for the html variant of the resource.
Isn't this what content negotiation is for?
from json-api.
Isn't this what content negotiation is for?
Do you mean this?
GET /articles/1 HTTP/1.1
Accept: text/html
Than it would only work for the same resource in another content type. E.g. only a single link per resource. That only allows html
(or something alike) as extra link, not the freedom of multiple custom links.
Plus it would give a bit ugly urls for end users I'd say. Somewhere in the url (host/path) is probably an api
keyword. You can redirect and such but I think that complicates the API server.
from json-api.
Related Issues (20)
- Is there any way to include not related models into a model for JsonApiFramework 2.8.0? HOT 2
- Provide JSON Schema for JSON:API 1.1 HOT 2
- Provide an updates list/blog HOT 9
- 1.1 seems to contain a breaking change - 'lid' now required for resource creation? HOT 2
- How is 'lid' actually used? The 1.1 spec says nothing about this HOT 13
- Why the square bracket syntax for query params? HOT 7
- consider support for implementation-specific members HOT 2
- JSON-LD integration example HOT 1
- Clarify intent of links member HOT 1
- How does one document a JSON:API HOT 4
- 1.1 spec disallows e.g. filter[author.name] HOT 4
- Inclusion of related resources for heterogeneous collections
- PrimaryResourceType not to be null at this point HOT 1
- Create/update relationships having attributes? HOT 3
- ember-data link on implementations page is broken HOT 2
- Bulk delete as either extention or implementation HOT 4
- Extend Spec To Allow Creation of Multiple Resources in One API Call HOT 1
- Profiles should be allowed to define query parameters HOT 5
- JSONRenderer does not extract includes from PolymorphicModelSerializer properly HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from json-api.