Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 292486

Links with different target attributes are improperly merged

$
0
0

Problem/Motivation

According to RFC8288, a link is:

a typed connection between two resources and is comprised of:

  • a link context,
  • a link relation type (Section 2.1),
  • a link target, and
  • optionally, target attributes (Section 2.2).

When LinkCollection::merge merges two Link objects with the same key and target URI, it does not consider target attributes as a differentiating factor.

An example where this can break link semantics in via the anchor target attribute. Typically, a "link context" is just the resource on which a link appears, however, a link context can be overridden by the anchor target attribute. When JSON:API merges links, it only considers the links object key and the target URI to determine if a link is equivalent. In the case that one link defines an anchor and the other does not, the semantics of the link without the anchor will be broken. Consider the following example (appearing on a resource /bar):

1. {"href": "/foo", "anchor": "/foo/alias", "rel": ["canonical"]}
2. {"href": "/foo", "rel": ["related"]}

These JSON objects are simplified. Real JSON:API link objects look different.

would be merged into:

3. {"href": "/foo", "rel": ["related", "canonical"], "anchor": "/foo/alias"}

Another example where this can be an issue is when two links share a common URI but different link relation types and target attributes:

1. {"href": "/foo", "rel": ["comments"], "title": "Comments on Foo"}
2. {"href": "/foo", "rel": ["add-comment"], "title": "Post a comment about Foo"}

would be merged into:

3. {"href": "/foo", "rel": ["comments", "add-comment"], "title": ["Comments on Foo", "Post a comment about Foo"]}

After that merge, it's impossible to know which of the two links represented by the merged object has which title. The semantics of the link object are pretty much nonsensical.

For background, the reason that Drupal\jsonapi\JsonApiResource\Link support more than one link relation type and merging of this kind is because RFC 8288 permits a Linkheader to have more than one link relationship type and, apparently, I misread the RFC (mea culpa). In the following paragraph, I saw the first sentence, but didn't internalize the second sentence:

The rel parameter can, however, contain multiple link relation types. When this occurs, it establishes multiple links that share the same context, target, and target attributes. — Section 3.3 (emphasis added)

Proposed resolution

  1. Deprecate passing an array of link relation types to Link::__construct in favor of a single string
  2. Deprecate Link::getLinkRelationTypes (plural) in favor of Link::getLinkRelationType
  3. Update Link::compare to only treat equivalent links as equal (it currently ignores target attributes)
  4. Update Link::merge to only merge cacheability, since links with different relation types or attributes can no longer be merged

User interface changes

None.

API changes

Link::__construct will have a deprecated argument type. Note: Drupal\jsonapi\JsonApiResource\Link is an @internal value object and no JSON:API code actually uses multiple link relation types or target attributes.

It's also important to note that there is currently no public API for adding custom links to JSON:API responses.

Data model changes

None.

Release notes snippet

None.


Viewing all articles
Browse latest Browse all 292486

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>