dret / I-D

Internet Drafts I've authored or contributed to.
16 stars 13 forks source link

allowing multiple link relation types in rel in the JSON serialization #122

Closed dret closed 4 years ago

dret commented 5 years ago

this was raised by @gabesullice (https://httpapis.slack.com/archives/C1JQJUF2T/p1567024238000700?thread_ts=1567009616.000200&cid=C1JQJUF2T):

[...] (deleted because @gabesullice now submitted his own version.)

gabesullice commented 5 years ago

Here is my formatted message:


I think there might be an inconsistency between application/linkset and application/linkset+json

The link header serialization says "The rel parameter can, however, contain multiple link relation types." https://tools.ietf.org/html/rfc8288#section-3.3

However, in the JSON serialization you define, it appears that it can only support a single link relation type.

Unless you mean for user agents to:

a. deduplicate links that share a common context and target but a different rel b. interpret the object property name as a space-delimited set of relation types

If either of those is the case, I think it would be good to explicitly give that example.

OTOH, I think I would prefer if your link object replaced the rel as object property name with the constant, target, and make rel a sibling of href, permitting it to be an array

hvdsomp commented 5 years ago

Could it be that you are reacting to version 3 of the Internet Draft, and not version 4 that was released today? See https://tools.ietf.org/html/draft-wilde-linkset-04

gabesullice commented 5 years ago

@hvdsomp, I followed @dret's tweet directly to version 4.

Here is the line in question: https://github.com/dret/I-D/blob/master/linkset/draft-wilde-linkset-04.txt#L351

Specifically:

For each distinct relation type that the link context has with link targets, a link context object MUST have an additional member. ... The name of this member expresses the relation type of the link as follows:

  • ... the name of this member is the registered name of the relation type.

Consequently, a link context object can have one ore more link target objects but those links can only have a single relation type.

The example also makes this clear:

   {
     "linkset":
       [
         { "anchor":"http://example.net/bar",
           "item": [
                 {"href": "http://example.com/foo1"},
                 {"href": "http://example.com/foo2"}
           ]
         }
       ]
   }

Which we can reformat into a link header as:

Link: <http://example.com/foo1>; rel="item" anchor="http://example.net/bar" ,
  <http://example.com/foo1>; rel="item" anchor="http://example.net/bar"

However, how would one serialize this link header back into JSON?

Link: <http://example.com/foo1>; rel="item http://example.net/relation/other1" anchor="http://example.net/bar",
  <http://example.com/foo2>; rel="item http://example.net/relation/other2" anchor="http://example.net/bar"

It's not clear in the current draft (v4). There is an example of a link header with multiple link relation types in RFC 8288 (search for http://example.net/relation/other).

What I proposed at the end of my message would look like this:

   {
     "linkset":
       [
         { "anchor":"http://example.net/bar",
           "target": [
                 {"href": "http://example.com/foo1",
                  "rel": ["item", "http://example.net/relation/other1"]},
                 {"href": "http://example.com/foo2",
                  "rel": ["item", "http://example.net/relation/other2"]}
           ]
         }
       ]
   }
hvdsomp commented 5 years ago

According to the current spec 04, these links conveyed in a Link header:

Link: <http://example.com/foo1>; rel="item http://example.net/relation/other1" anchor="http://example.net/bar",
  <http://example.com/foo2>; rel="item http://example.net/relation/other2" anchor="http://example.net/bar"

would be expressed as JSON as follows:

{
  "linkset": [
    {
      "anchor": "http://example.net/bar",
      "item": [
        {
          "href": "http://example.com/foo1"
        },
        {
          "href": "http://example.com/foo2"
        }
      ],
      "http://example.net/relation/other1": [
        {
          "href": "http://example.com/foo1"
        }
      ],
      "http://example.net/relation/other2": [
        {
          "href": "http://example.com/foo2"
        }
      ]
    }
  ]
}

You are right that the current I-D does not provide such an example and I agree that it should.

At first glance, it looks like the syntax you propose could also be a possibility. We have based the current approach on input from @stain and his proposal was inspired by the JSON serialization used for the W3C Web Annotation Data Model. A requirement that resulted from interactions with @stain and @csarven about the serialization is that it should be possible to turn the JSON serialization into a JSON-LD one by adding context. The I-D mentions this.

stain commented 5 years ago

I agree that the "multiple rel" use case is not supported by the JSON and have to be unrolled as multiple link relations. On the other hand the JSON supports multiple targets for the same link relation.

We can theorise that it is likely a consumer of linksets are primarily interested in following a particular type of links (say alternate) as opposed to finding out which relations are used against a given target URL.

Similarly the JSON does not distinguish between individual Link: lines or several relations joined on a single Link line, or even the order of the links across relation types. These would all be syntactic differences which do not change the semantics - I am not quite sure what is the use case to preserve those across syntaxes.

gabesullice commented 5 years ago

Something I should have pointed out in my original issue is that the primary reason for allowing multiple link relation types is not because it's already allowed by the header serialization, but because being able to specify more than one link relation type allows the user to compose link relation types.

I suppose this can be accomplished in other ways, JSON-Home simply allows compound link relation types using a comma-separated syntax. That doesn't seem very elegant though.

dret commented 5 years ago

On Sep 6, 2019, at 21:39, Gabe Sullice notifications@github.com wrote:

Something I should have pointed out in my original issue is that the primary reason for allowing multiple link relation types is not because it's already allowed by the header serialization, but because being able to specify more than one link relation type allows the user to compose link relation types.

i'd say you cannot really compose types, but you can create links with multiple types. the difference is subtle, but relevant.

keeping the serialization equivalent to RFC 8288 is important, so that links can be serialized either way with no special cases or exceptions.

two links with single types are not the same as one link with two types. it seems like the JSON encoding currently is missing something that's relevant. changing the link relation type to an array seems to be the most JSON-idiomatic way to address this?

hvdsomp commented 5 years ago

I do not think there is such a thing as a link with multiple relation types. I deduce that from reading Section 2 and Section 2.1 of the Web Linking RFC. It clearly defines a link as a thing with a context, a relation type, and a target. It does not state “one or more relation types”.

The RFC is also explicit that no additional semantics can be derived from the fact that two links with same context and target have different relation types, ie there is no additional meaning in the combination of relation types:

Relation types SHOULD NOT infer any additional semantics based upon
   the presence or absence of another link relation type, or its own
   cardinality of occurrence.

As such, I regard the fact that one can express multiple relation types between the same context and target in the Link header serialization a mere artifact of that serialization and not something that the Web Linking defines as the model for a link. As such, IMO, there is no pressing reason to provide the same serialization functionality in JSON.

dret commented 5 years ago

On 2019-09-07 09:16, Herbert Van de Sompel wrote:

I do not think there is such a thing as a link with multiple relation types. I deduce that from reading Section 2 https://tools.ietf.org/html/rfc8288#section-2 and Section 2.1 https://tools.ietf.org/html/rfc8288#section-2.1 of the Web Linking RFC. It clearly defines a link as a thing with a context, a relation type, and a target. It does not state “one or more relation types”.

true. i should have remembered that section, thanks for reminding me.

As such, I regard the fact that one can express multiple relation types between the same context and target in the Link header serialization a mere artifact of that serialization and not something that the Web Linking defines as the model for a link. As such, IMO, there is no pressing reason to provide the same serialization functionality in JSON.

+1 after that clarification. so maybe add an example pointing to this difference in the serialization approach, and also pointing out that this makes no difference semantically.

dret commented 4 years ago

done.