GithubHelp home page GithubHelp logo

Allow custom resource links about json-api HOT 13 OPEN

toedter avatar toedter commented on June 11, 2024
Allow custom resource links

from json-api.

Comments (13)

freddrake avatar freddrake commented on June 11, 2024 1

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 avatar jelhan commented on June 11, 2024 1

@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.

jelhan avatar jelhan commented on June 11, 2024 1

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.

jelhan avatar jelhan commented on June 11, 2024

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.

toedter avatar toedter commented on June 11, 2024

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.

jelhan avatar jelhan commented on June 11, 2024

Please see #1019 and #1656 for previous discussions on this topic.

from json-api.

toedter avatar toedter commented on June 11, 2024

@jelhan thx for the pointers.

from json-api.

toedter avatar toedter commented on June 11, 2024

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:

  1. Use relationships to express relations between rest resources
  2. When using links, stick to the allowed members
  3. 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.

jelhan avatar jelhan commented on June 11, 2024

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

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.

jelhan avatar jelhan commented on June 11, 2024

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.

lode avatar lode commented on June 11, 2024

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.

freddrake avatar freddrake commented on June 11, 2024

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.

lode avatar lode commented on June 11, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.