RFC 9264
Linkset: Media Types and a Link Relation Type for Link Sets
Linkset: Media Types and a Link Relation Type for Link Sets β¨
okay bestie, the header info first π. This is RFC 9264, published in July 2022 by the Internet Engineering Task Force (IETF). The authors are E. Wilde from Axway and H. Van de Sompel from Data Archiving and Networked Services. It's a Standards Track document, ISSN 2070-1721. The title block doesn't list anything it obsoletes or updates, so it's standing on its own π .
Abstract
okay so this spec defines two formats and their media types for sets of links, shipped as standalone documents π¦. One format is JSON-based, and the other lines up with the format used for links in the HTTP "Link" header field. It also introduces a link relation type so you can discover those sets of links π. literally a whole toolkit.
Status of This Memo
this is an Internet Standards Track document π. It's a product of the IETF, so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check out Section 2 of RFC 7841 π.
info about the current status, any errata, and how to send feedback lives at https://www.rfc-editor.org/info/rfc9264 πΈ.
Copyright Notice
Β© 2022 IETF Trust and the persons identified as the document authors, all rights reserved π. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as in effect on the publication date. read those carefully, bestie, because they explain your rights and restrictions π.
if you extract Code Components from this document, they must include the Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions. They come without warranty, as described in the Revised BSD License β οΈ.
Table of Contents
1. Introduction
2. Terminology
3. Use Cases and Motivation
3.1. Third-Party Links
3.2. Challenges Writing to the HTTP "Link" Header Field
3.3. Large Number of Links
4. Document Formats for Sets of Links
4.1. HTTP Link Document Format: application/linkset
4.2. JSON Document Format: application/linkset+json
4.2.1. Set of Links
4.2.2. Link Context Object
4.2.3. Link Target Object
4.2.4. Link Target Attributes
4.2.5. JSON Extensibility
5. The "profile" Parameter for Media Types to Represent Sets of
Links
6. The "linkset" Relation Type for Linking to a Set of Links
7. Examples
7.1. Set of Links Provided as "application/linkset"
7.2. Set of Links Provided as "application/linkset+json"
7.3. Discovering a Link Set via the "linkset" Link Relation Type
7.4. Link Set Profiles
7.4.1. Using a "profile" Attribute with a "linkset" Link
7.4.2. Using a "profile" Parameter with a Link Set Media Type
7.4.3. Using a Link with a "profile" Link Relation Type
8. IANA Considerations
8.1. Link Relation Type: linkset
8.2. Media Type: application/linkset
8.3. Media Type: application/linkset+json
9. Security Considerations
10. References
10.1. Normative References
10.2. Informative References
Appendix A. JSON-LD Context
Acknowledgements
Authors' Addresses
1. Introduction β¨
okay so resources on the Web often use typed Web Links [RFC8288] π. You can embed them in the representation, like a <link> element in an HTML document, or send them in the HTTP "Link" header field for documents of any media type. sometimes though, doing it that way is impractical or impossible, and sending a set of links as its own standalone document is the move π.
so this spec defines two formats for representing sets of Web Links and their attributes as standalone documents π¦. One format serializes links the same way the HTTP "Link" header field does, and the other serializes them in JSON. It also defines the media types for these sets of links, plus the "linkset" relation type, which helps you discover any resource that delivers a set of links as a standalone document π.
2. Terminology π
here's the caps-lock part, bestie π. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
this spec uses "link context" and "link target" the same way "Web Linking" [RFC8288] does π§.
in the examples, links in the HTTP "Link" header field are split across separate lines so they're easier to read π. ngl, though, line breaks are deprecated in values for HTTP fields. Per Section 5.5 of "HTTP Semantics" [RFC9110], only whitespaces and tabs are supported as separators π.
3. Use Cases and Motivation π
these sections walk through the use cases where a standalone document beats the HTTP "Link" header field or links embedded in the resource representation. It's either advantageous or necessary there π.
for every scenario, the links could come as a standalone document in the JSON-based serialization, the one aligned with the HTTP "Link" field format, or both π. The JSON one exists because JSON and its tools are everywhere, so handling sets of links as JSON documents should feel really attractive to developers β¨. The other one exists for compatibility with the serialization already used in the HTTP "Link" field, and so you can reuse tools built to handle it π οΈ.
keep in mind that when you provide links as a standalone representation, other links can still come through other approaches. It's totally possible to mix and match mechanisms to convey links π¦.
3.1. Third-Party Links π
sometimes it's useful for links about a resource to come from a server other than the one hosting that resource π. This allows:
- Providing links where the resource is a link target, while a different resource is the link context.
- Providing links about the resource that the server hosting it doesn't know about.
- Managing links about the resource externally, in a special-purpose link management service.
in those cases, links about a resource can be provided by another, specific resource πΈ. That specific resource might be managed by the same custodian as the resource the links pertain to, or by a different custodian. For clients who want to consume links provided that way, it'd be really beneficial if these conditions were met:
- Links are provided in a document that uses a well-defined media type.
- The resource the links pertain to can link to the resource that provides them, using a well-known link relation type.
this spec handles those requirements with two media types and a link relation type, respectively π.
3.2. Challenges Writing to the HTTP "Link" Header Field π
sometimes writing links to the HTTP "Link" header field from an application is just not straightforward π₯Ί. For example, not all the required link information might be available to the application, or the application might not be able to write HTTP fields directly. In those cases, a standalone document can be the solution π. You can make the resource that provides these links discoverable with a typed link π.
3.3. Large Number of Links π
when links go into an HTTP "Link" header field, the size of the HTTP response fields can get unpredictable π΅. That happens when links are determined dynamically, depending on a whole bunch of contextual factors. A web server can be configured to handle large HTTP response fields by setting an upper bound on their size. but when the number of links is unpredictable, estimating a reliable upper bound is genuinely hard π« .
Section 15 of "HTTP Semantics" [RFC9110] defines error codes for excess communication by the user agent ("413 Content Too Large" and "414 URI Too Long"). But no specific error code says that response field content went past the upper bound the server can handle and got truncated π ββοΈ. So applications take countermeasures to control the size of the HTTP "Link" header field. For example, they limit the links they provide to ones with select relation types, which limits the value clients see π§’. A standalone document gets around all of this, because the unpredictable (to the web server implementation) size of HTTP "Link" header fields stops being a problem π¦.
4. Document Formats for Sets of Links β¨
okay bestie, this is where we get to the actual formats π This section defines two document formats for carrying a set of links. Both are built on the abstract model from Section 2 of "Web Linking" [RFC8288], where a link is made of a "link context", a "link relation type", a "link target", and optional "target attributes" π¦
- The format in Section 4.1 is nearly identical to the field value of the HTTP "Link" header field from Section 3 of [RFC8288] π
- The format in Section 4.2 is written in JSON [RFC8259] π
Links in the HTTP "Link" header field are meant to be used during an HTTP interaction, and the info available in that interaction is what helps read them correctly πΈ Links in link sets can get reused outside an HTTP interaction, where that context just isn't there π So implementers should aim to make their link sets self-contained by following the recommendations below π«Ά
For links in the HTTP "Link" header field that have no anchor or that use relative references, the URI of the resource that delivers the links provides the context needed to interpret them. So that link set documents can be reused outside an HTTP interaction, it is RECOMMENDED to make them self-contained by following these guidelines:
- For every link provided in the set of links, explicitly provide the link context using the "anchor" attribute.
- For the link context ("anchor" attribute) and link target ("href" attribute), use URI references that are not relative references (as defined in Section 4.1 of [RFC3986]).
If these recommendations aren't followed, the interpretation of links in link set documents will depend on which URI is used as the context π
Now the title situation π For a "title" attribute on a link in the HTTP "Link" header field, the language of the title comes from the "Content-Language" header field of the HTTP interaction with the resource that delivers the links. This does not apply to "title" attributes on links in link set documents, because that would force every link in a set to have one single title language, and it wouldn't let you figure out title languages when a link set is used outside an HTTP interaction. So, to support reuse outside HTTP, it is RECOMMENDED to make link sets self-contained by using the "title*" attribute instead of the "title" attribute. "title*" lets you put the title language right into its value with a language tag. Note that, in this regard, language tags are matched case insensitively (see Section 2.1.1 of [RFC5646]). If this recommendation isn't followed, accurately determining the language of titles on links in link set documents won't be possible π
Also, Section 3.3 of [RFC8288] deprecates the "rev" construct that [RFC5988] provided for expressing links with the inverse directionality of direct links that use the "rel" construct. In both serializations for link sets defined here, inverse links may be represented as direct links using the "rel" construct and by switching the roles of the resources involved in the link π
4.1. HTTP Link Document Format: application/linkset π
This document format is nearly identical to the field value of the HTTP "Link" header field as defined in Section 3 of [RFC8288], more specifically by its ABNF [RFC5234] production rule for "Link" and its subsequent rules. It differs from the format for field values of the HTTP "Link" header field only in that not only spaces and horizontal tabs are allowed as separators but also newline characters, as a means to improve readability for humans π The use of non-ASCII characters in the field value of the HTTP "Link" header field is not allowed, and as such it's also not allowed in application/linkset link sets π«
The assigned media type for this format is application/linkset.
When converting an application/linkset document to a field value for the HTTP "Link" header field, newline characters MUST be removed or MUST be replaced by whitespace (SP) in order to comply with Section 5.5 of [RFC9110]. Main character energy: the conversion has to be tidy π
Implementers of application/linkset link sets should strive to make them self-contained by following the recommendations provided in Section 4 regarding their use outside the context of an HTTP interaction.
It should be noted that the application/linkset format specified here is different from the application/link-format format specified in [RFC6690]. The former fully matches the field value of the HTTP "Link" header field as defined in Section 3 of [RFC8288], whereas the latter introduces constraints on that definition to meet requirements for Constrained RESTful Environments (CoRE) π§
4.2. JSON Document Format: application/linkset+json π
This document format uses JSON [RFC8259] as the syntax to represent a set of links. The set of links follows the abstract model defined by Section 2 of [RFC8288] π
The assigned media type for this format is application/linkset+json.
For interoperability's sake, application/linkset+json link sets MUST be encoded using UTF-8 as per Section 8.1 of [RFC8259] π«Ά
Implementers of application/linkset+json link sets should strive to make them self-contained by following the recommendations provided in Section 4 regarding their use outside the context of an HTTP interaction.
The application/linkset+json serialization allows for OPTIONAL support of a JSON-LD serialization πΈ This can be achieved by adding an appropriate context to the application/linkset+json serialization, using the approach described in Section 6.1 of [W3C.REC-json-ld]. Communities of practice can decide which context best meets their application needs. Appendix A shows an example of a possible context that, when added to a JSON serialization, allows it to be interpreted as Resource Description Framework (RDF) data [W3C.REC-rdf11-concepts] π§ β¨
4.2.1. Set of Links π
In the JSON representation of a set of links:
- A set of links is represented in JSON as an object that MUST contain
"linkset"as its sole member. - The value of the
"linkset"member is an array in which a distinct JSON object -- the "link context object" (see Section 4.2.2) -- is used to represent links that have the same link context. - Even if there is only one link context object, it MUST be wrapped in an array.
4.2.2. Link Context Object π¦
In the JSON representation, one or more links that have the same link context are represented by a JSON object -- the link context object. A link context object adheres to the following rules:
- Each link context object MAY contain an
"anchor"member with a value that represents the link context. If present, this value MUST be a URI reference and SHOULD NOT be a relative reference as defined in Section 4.1 of [RFC3986]. - For each distinct relation type that the link context has with link targets, a link context object MUST contain an additional member. The value of this member is an array in which a distinct JSON object -- the "link target object" (see Section 4.2.3) -- MUST be used for each link target for which the relationship with the link context (value of the encompassing
"anchor"member) applies. The name of this member expresses the relation type of the link as follows: - Even if there is only one link target object, it MUST be wrapped in an array.
4.2.3. Link Target Object π―
In the JSON representation, a link target is represented by a JSON object -- the link target object. A link target object adheres to the following rules:
- Each link target object MUST contain an
"href"member with a value that represents the link target. This value MUST be a URI reference and SHOULD NOT be a relative reference as defined in Section 4.1 of [RFC3986]. Cases where the"href"member is present but no value is provided for it (i.e., the resource providing the set of links is the target of the link in the link target object) MUST be handled by providing an"href"member with an empty string as its value ("href": ""). - In many cases, a link target is further qualified by target attributes. Various types of attributes exist, and they are conveyed as additional members of the link target object as detailed in Section 4.2.4.
Here's a JSON-serialized set of links representing one link with its core components: link context, link relation type, and link target π°
{ "linkset":
[
{ "anchor": "https://example.net/bar",
"next": [
{"href": "https://example.com/foo"}
]
}
]
}
Figure 1: Simple linkset example
Next up, a JSON-serialized set of links representing two links that share a link context and relation type but have different link targets π―
{ "linkset":
[
{ "anchor": "https://example.net/bar",
"item": [
{"href": "https://example.com/foo1"},
{"href": "https://example.com/foo2"}
]
}
]
}
Figure 2: Linkset with two links with the same context
And this one is a set of links representing two links, each with a different link context, link target, and relation type. One relation type is registered and the other is an extension relation type π
{ "linkset":
[
{ "anchor": "https://example.net/bar",
"next": [
{"href": "https://example.com/foo1"}
]
},
{ "anchor": "https://example.net/boo",
"https://example.com/relations/baz" : [
{"href": "https://example.com/foo2"}
]
}
]
}
Figure 3: Linkset with two links with different contexts
4.2.4. Link Target Attributes π·
A link may be further qualified by target attributes as defined by Section 2 of [RFC8288]. Three types of attributes exist:
- Serialization-defined attributes as described in Section 3.4.1 of [RFC8288].
- Extension attributes defined and used by communities as allowed by Section 3.4.2 of [RFC8288].
- Internationalized versions of the "title" attribute as defined by [RFC8288] and of extension attributes allowed by Section 3.4 of [RFC8288].
The handling of these different types of attributes is described in the sections below β¨
4.2.4.1. Target Attributes Defined by Web Linking β¨
okay so, [RFC8288] has a list of target attributes you can use to annotate links in Section 3.4.1 of [RFC8288] π. The ones it defines are hreflang, media, title, title*, and type, and they don't all follow the same rules for how many you can have or what the values look like π
. In the JSON representation, these attributes MUST be conveyed as additional members of the link target object, as follows π¦
hreflang: this one is optional and repeatable according to [RFC8288] π. It MUST be represented by ahreflangmember, its value MUST be an array (even if there's only one value, bestie), and each value in that array MUST be a string. Each string represents onehreflangvalue for a link, and it follows the same model as the syntax discussed in [RFC8288] π«Άmedia: this one is optional and NOT repeatable according to [RFC8288] π. It MUST be represented by amediamember in the link target object, and its value MUST be a string that follows the same model as the syntax discussed in [RFC8288] β¨title: also optional and not repeatable π. It MUST be represented by atitlemember in the link target object, and its value MUST be a JSON string πΈtitle*: optional and not repeatable too π§. This one is all about character encoding and language issues, and it follows the model defined in [RFC8187] π. The details of howtitle*gets represented in JSON are in Section 4.2.4.2, so go check that out πtype: optional and not repeatable π. It MUST be represented by atypemember in the link target object, and its value MUST be a string that follows the same model as the syntax discussed in [RFC8288] π
Here's a little example showing how the repeatable hreflang and the non-repeatable type look in a link target object π
{ "linkset":
[
{ "anchor": "https://example.net/bar",
"next": [
{ "href": "https://example.com/foo",
"type": "text/html",
"hreflang": [ "en" , "de" ]
}
]
}
]
}
Figure 4: Linkset with "hreflang" and "type" target attributes
4.2.4.2. Internationalized Target Attributes π
Okay, so on top of the target attributes from Section 4.2.4.1, Section 3.4 of [RFC8288] also supports attributes that follow the content model of [RFC8187] π¦. In [RFC8288], you can spot these by the trailing asterisk in the name, like title* π. The [RFC8187] content model is a string-based microsyntax that carries the character encoding, an optional language tag, and the escaped attribute value, which is encoded according to that character encoding β¨
The JSON serialization for these target attributes MUST be as follows π«Ά
- An internationalized target attribute is represented as a member of the link context object, with the same name as the attribute (including the "*") π
- The character encoding information prescribed by [RFC8187] is NOT preserved π. Instead, the content of the internationalized attribute is represented as a JSON string πΈ
- The value of the internationalized target attribute is an array that contains one or more JSON objects. One member of those objects is named "value", and its value is the actual content of the attribute in its unescaped version. That's the value with the encoding and language info stripped off π§. Another member, which is optional, is named "language", and its value is the language tag [RFC5646] for the language the attribute content is in π
Here's how the title* target attribute from Section 3.4.1 of [RFC8288] looks in a link target object π
{ "linkset":
[
{ "anchor": "https://example.net/bar",
"next": [
{ "href": "https://example.com/foo",
"type": "text/html",
"hreflang": [ "en" , "de" ],
"title": "Next chapter",
"title*": [ { "value": "nΓ€chstes Kapitel" ,
"language" : "de" } ]
}
]
}
]
}
Figure 5: Linkset with "title" and "title*" target attributes
This example assumes the German title has an umlaut character. In the original syntax it would be encoded as title*=UTF-8'de'n%c3%a4chstes%20Kapitel, but in the JSON representation it shows up in its unescaped form π. Implementations MUST properly decode/encode internationalized target attributes that follow the model of [RFC8187] when transcoding between the "application/linkset" format and the "application/linkset+json" format π₯
4.2.4.3. Extension Target Attributes π§©
Extension target attributes (like the ones listed in Section 4.2.4.1) are attributes that aren't defined by Section 3.4.1 of [RFC8288] but still get used to qualify links π . Communities can define them however they need to, and it's up to them to make sure their usage is understood by target applications π«Ά. BUT, without standardization there's no interoperable understanding of these extension attributes π. One big consequence is that their cardinality is unknown to generic applications, so in the JSON serialization, all extension target attributes are treated as repeatable πΈ
The JSON serialization for these target attributes MUST be as follows π¦
- An extension target attribute is represented as a member of the link target object with the same name as the attribute, including the "*" if applicable π
- The value of an extension attribute MUST be represented by an array, even if there's only one value π
- If the extension target attribute doesn't have a name with a trailing asterisk, then each value in that array MUST be a JSON string that represents one value of the attribute π
- If the extension attribute has a name with a trailing asterisk (it follows the content model of [RFC8187]), then each value in that array MUST be a JSON object. The value of each such JSON object MUST be structured as described in Section 4.2.4.2 β¨
This example shows a link target object with three extension target attributes, and each value is an array π§. The first two are regular extension target attributes: foo has only one value and bar has two. The last one, baz*, follows the naming rule of [RFC8187], so it's encoded using the serialization from Section 4.2.4.2 π
{ "linkset":
[
{ "anchor": "https://example.net/bar",
"next": [
{ "href": "https://example.com/foo",
"type": "text/html",
"foo": [ "foovalue" ],
"bar": [ "barone", "bartwo" ],
"baz*": [ { "value": "bazvalue" ,
"language" : "en" } ]
}
]
}
]
}
Figure 6: Linkset with extension target attributes
4.2.5. JSON Extensibility π
The Web Linking model in [RFC8288] lets you use extension target attributes, as covered in Section 4.2.4.3 π. Using any other kind of extension is NOT RECOMMENDED π. Keeping the JSON format this limited is what allows unambiguous round trips between links in the HTTP Link header field, sets of links serialized as application/linkset, and sets of links serialized as application/linkset+json π
Sometimes other extensions, beyond the ones in Section 4.2.4.3, might be useful. For example, a link set publisher might need to include descriptive or technical metadata for internal use π. If you do use those extensions, they MUST NOT change the semantics of the JSON members defined in this specification. Agents that consume JSON linkset documents can safely ignore them π«Ά
5. The "profile" Parameter for Media Types to Represent Sets of Links β¨
So, as a way to convey specific constraints or conventions (as per [RFC6906]) that apply to a link set document, the profile parameter MAY be used with the media types application/linkset and application/linkset+json, as detailed in Sections 4.1 and 4.2 respectively π¦. For example, it could be used to show that a link set only uses a specific, limited set of link relation types π
The value of the profile parameter MUST be a non-empty list of space-separated URIs. Each URI identifies specific constraints or conventions that apply to the link set document π. When you give multiple profile URIs, take care that the profiles don't conflict with each other π§. Profile URIs MAY be registered in the IANA's "Profile URIs" registry, in the manner specified by [RFC7284] πΈ
Having a profile parameter with the application/linkset and application/linkset+json media types doesn't change the semantics of a link set π. So clients that know about profile URIs and clients that don't can use the same representation π«Ά
Section 7.4.2 shows an example of using the profile parameter with the application/linkset+json media type π§
6. The "linkset" Relation Type for Linking to a Set of Links β¨
okay so the target of a link with the "linkset" relation type is basically a whole bundle of links π, and that bundle can include links where the resource that's the link context is part of the action too π
A link with the "linkset" relation type MAY be provided in the header field and/or the body of a resource's representation. It may also be discovered by other means, such as through client-side information. π«Ά
A resource MAY provide more than one link with a "linkset" relation type. Multiple links like that can point to the same set of links in different media types, or to totally different sets, maybe even ones provided by different third-party services π
The set of links provided by the resource that is the target of a "linkset" link may contain links where the resource that's the context of the "linkset" link doesn't participate. User agents MUST process each link in the link set independently, including processing of the link context and link target, and MAY ignore links from the link set where the context of the "linkset" link doesn't participate. It's giving independence, honestly π
A user agent that follows a "linkset" link and obtains links whose anchors and targets are expressed as relative references (as per Section 4.1 of [RFC3986]) MUST determine what the context is for those links. If it can't unambiguously make that determination, it SHOULD ignore those links π
As a way to convey specific constraints or conventions (as per [RFC6906]) that apply to a link set document, the "profile" attribute MAY be used in conjunction with the "linkset" link relation type. For example, the attribute could be used to show that a link set uses a specific, limited set of link relation types π The value of the "profile" attribute MUST be a non-empty list of space-separated URIs, and each one identifies specific constraints or conventions that apply to the link set document. Profile URIs MAY be registered in the IANA's "Profile URIs" registry in the manner specified by [RFC7284]. Section 7.4.1 shows an example of using the "profile" attribute on a link with the "linkset" relation type, making both the link set and the profile(s) it complies with discoverable π¦
7. Examples π
Sections 7.1 and 7.2 show examples where a set of links is provided as "application/linkset" and "application/linkset+json" documents, respectively. Section 7.3 illustrates how the "linkset" link relation type supports discovery of sets of links, and Section 7.4 shows how to convey profile information about a link set π
7.1. Set of Links Provided as "application/linkset"
Figure 7 shows a client issuing an HTTP GET request against the resource <https://example.org/links/resource1>.
GET /links/resource1 HTTP/1.1
Host: example.org
Figure 7: Client HTTP GET request
Figure 8 shows the response to the GET request of Figure 7. The response contains a "Content-Type" header field specifying that the media type of the response is "application/linkset". A set of links revealing authorship and versioning for the resource <https://example.org/resource1> is provided in the response body. The HTTP "Link" header field indicates the availability of an alternate representation of the set of links using the media type "application/linkset+json" π
HTTP/1.1 200 OK
Date: Mon, 12 Aug 2019 10:35:51 GMT
Server: Apache-Coyote/1.1
Content-Length: 1023
Content-Type: application/linkset
Link: <https://example.org/links/resource1>
; rel="alternate"
; type="application/linkset+json"
<https://authors.example.net/johndoe>
; rel="author"
; type="application/rdf+xml"
; anchor="https://example.org/resource1",
<https://example.org/resource1?version=3>
; rel="latest-version"
; type="text/html"
; anchor="https://example.org/resource1",
<https://example.org/resource1?version=2>
; rel="predecessor-version"
; type="text/html"
; anchor="https://example.org/resource1?version=3",
<https://example.org/resource1?version=1>
; rel="predecessor-version"
; type="text/html"
; anchor="https://example.org/resource1?version=2",
<https://example.org/resource1?version=1>
; rel="memento"
; type="text/html"
; datetime="Thu, 13 Jun 2019 09:34:33 GMT"
; anchor="https://example.org/resource1",
<https://example.org/resource1?version=2>
; rel="memento"
; type="text/html"
; datetime="Sun, 21 Jul 2019 12:22:04 GMT"
; anchor="https://example.org/resource1",
<https://authors.example.net/alice>
; rel="author"
; anchor="https://example.org/resource1#comment=1"
Figure 8: Response to HTTP GET includes a set of links
7.2. Set of Links Provided as "application/linkset+json"
Figure 9 shows the client issuing an HTTP GET request against <https://example.org/links/resource1>. In the request, the client uses an "Accept" header field to indicate that it prefers a response in the "application/linkset+json" format πΈ
GET links/resource1 HTTP/1.1
Host: example.org
Accept: application/linkset+json
Figure 9: Client HTTP GET request expressing preference for an "application/linkset+json" response
Figure 10 shows the response to the HTTP GET request of Figure 9. The set of links is serialized according to the media type "application/linkset+json" β¨
HTTP/1.1 200 OK
Date: Mon, 12 Aug 2019 10:46:22 GMT
Server: Apache-Coyote/1.1
Content-Type: application/linkset+json
Link: <https://example.org/links/resource1>
; rel="alternate"
; type="application/linkset"
Content-Length: 1246
{ "linkset":
[
{ "anchor": "https://example.org/resource1",
"author": [
{ "href": "https://authors.example.net/johndoe",
"type": "application/rdf+xml"
}
],
"memento": [
{ "href": "https://example.org/resource1?version=1",
"type": "text/html",
"datetime": "Thu, 13 Jun 2019 09:34:33 GMT"
},
{ "href": "https://example.org/resource1?version=2",
"type": "text/html",
"datetime": "Sun, 21 Jul 2019 12:22:04 GMT"
}
],
"latest-version": [
{ "href": "https://example.org/resource1?version=3",
"type": "text/html"
}
]
},
{ "anchor": "https://example.org/resource1?version=3",
"predecessor-version": [
{ "href": "https://example.org/resource1?version=2",
"type": "text/html"
}
]
},
{ "anchor": "https://example.org/resource1?version=2",
"predecessor-version": [
{ "href": "https://example.org/resource1?version=1",
"type": "text/html"
}
]
},
{ "anchor": "https://example.org/resource1#comment=1",
"author": [
{ "href": "https://authors.example.net/alice"}
]
}
]
}
Figure 10: Response to the client's request for the linkset
7.3. Discovering a Link Set via the "linkset" Link Relation Type
Figure 11 shows a client issuing an HTTP HEAD request against the resource <https://example.org/resource1>.
HEAD resource1 HTTP/1.1
Host: example.org
Figure 11: Client HTTP HEAD request
Figure 12 shows the response to the HEAD request of Figure 11. The response contains an HTTP "Link" header field with a link that has the "linkset" relation type. It indicates that a set of links is provided by the resource <https://example.org/links/resource1>, which provides a representation with the media type "application/linkset+json" π
HTTP/1.1 200 OK
Date: Mon, 12 Aug 2019 10:45:54 GMT
Server: Apache-Coyote/1.1
Link: <https://example.org/links/resource1>
; rel="linkset"
; type="application/linkset+json"
Content-Length: 236
Content-Type: text/html;charset=utf-8
Figure 12: Response to HTTP HEAD request
7.4. Link Set Profiles
The examples in this section illustrate the use of the "profile" attribute for a link with the "linkset" link relation type, and the "profile" attribute for a link set media type. The examples are inspired by the implementation of link sets by GS1 (the standards body behind many of the world's barcodes) π§
7.4.1. Using a "profile" Attribute with a "linkset" Link
Figure 13 shows a client issuing an HTTP HEAD request against trade item 09506000134352 at <https://id.gs1.org/01/9506000134352>.
HEAD /01/9506000134352 HTTP/1.1
Host: id.gs1.org
Figure 13: Client HTTP HEAD request
Figure 14 shows the server's response to the request of Figure 13, including a "linkset" link with a "profile" attribute that has the profile URI <https://www.gs1.org/voc/?show=linktypes> as its value. Dereferencing that URI yields a profile document that lists all the link relation types a client can expect when requesting the link set made discoverable by the "linkset" link. The link relation types are presented in abbreviated form, e.g., <gs1:activityIdeas>, whereas the actual link relation type URIs are available as hyperlinks on the abbreviations, e.g., <https://www.gs1.org/voc/activityIdeas>. For posterity, that profile document was saved in the Internet Archive at <https://web.archive.org/web/20210927160406/https://www.gs1.org/voc/?show=linktypes> on 27 September 2021 πΌ
HTTP/1.1 307 Temporary Redirect
Date: Mon, 27 Sep 2021 16:03:07 GMT
Server: nginx
Link: <https://id.gs1.org/01/9506000134352?linkType=all>
; rel="linkset"
; type="application/linkset+json"
; profile="https://www.gs1.org/voc/?show=linktypes"
Location: https://example.com/risotto-rice-with-mushrooms/
Figure 14: Response to the client's HEAD request, including a "profile" attribute for the "linkset" link
7.4.2. Using a "profile" Parameter with a Link Set Media Type
Figure 15 shows a client issuing an HTTP HEAD request against the link set <https://id.gs1.org/01/9506000134352?linkType=all> that was discovered through the HTTP interactions shown in Section 7.4.1 π«§
HEAD /01/9506000134352?linkType=all HTTP/1.1
Host: id.gs1.org
Figure 15: Client HTTP HEAD request
Figure 16 shows the server's response to the request of Figure 15. Note the "profile" parameter for the "application/linkset+json" media type, which has as its value the same profile URI <https://www.gs1.org/voc/?show=linktypes> that was used in Figure 14 π
HTTP/1.1 200 OK
Date: Mon, 27 Sep 2021 16:03:33 GMT
Server: nginx
Content-Type: application/linkset+json;
profile="https://www.gs1.org/voc/?show=linktypes"
Content-Length: 396
Figure 16: Response to the client's HEAD request, including a "profile" parameter for the "application/linkset+json" media type
7.4.3. Using a Link with a "profile" Link Relation Type β¨
okay so the response in Figure 16 from the link set resource is basically the same vibe as Figure 17, which uses the "profile" link relation type from [RFC6906] π
HTTP/1.1 200 OK
Date: Mon, 27 Sep 2021 16:03:33 GMT
Server: nginx
Content-Type: application/linkset+json
Link: <https://www.gs1.org/voc/?show=linktypes>; rel="profile"
Content-Length: 396
Figure 17: Response to the client's HEAD request, including a
"profile" link
bestie, a "profile" link like the one in Figure 17 can also live inside the link set document itself π Figure 18 shows what that looks like. Every link in a link set document should have an explicit anchor, and that's the rule we're vibing with here, so this link uses the link set's own URI as the anchor and the profile URI as the target. If you want more than one profile URI, you just use multiple "href" members π§
{ "linkset":
[
{ "anchor": "https://id.gs1.org/01/9506000134352?linkType=all",
"profile": [
{"href": "https://www.gs1.org/voc/?show=linktypes"}
]
},
{ "anchor": "https://id.gs1.org/01/9506000134352",
"https://gs1.org/voc/whatsInTheBox": [
{"href": "https://example.com/en/packContents/GB"}
]
}
]
}
Figure 18: A linkset that declares the profile it complies with,
using a "profile" link
8. IANA Considerations β¨
8.1. Link Relation Type: linkset
IANA has registered the link relation type below in the "Link Relation Types" registry, following Section 4.2 of [RFC8288] π¦
Relation Name: linkset
Description: The link target of a link with the "linkset" relation
type provides a set of links, including links in which the link
context of the link participates.
Reference: RFC 9264
8.2. Media Type: application/linkset
IANA has registered the Internet media type "application/linkset" for a linkset encoded as described in Section 4.1 in the "Media Types" registry, following [RFC6838] πΈ
Type name: application
Subtype name: linkset
Required parameters: N/A
Optional parameters: profile
Encoding considerations: Linksets are encoded according to the
definitions provided in [RFC8288]. The encoding discussed in
[RFC8288] is based on the general encoding rules specified by HTTP
[RFC9110] and allows specific parameters to be extended by the
indication of character encoding and language as defined by
[RFC8187].
Security considerations: The security considerations of RFC 9264
apply.
Interoperability considerations: N/A
Published specification: RFC 9264
Applications that use this media type: This media type is not
specific to any application, as it can be used by any application
that wants to interchange Web Links.
Additional information:
Magic number(s): N/A
File extension(s): This media type does not propose a specific
extension.
Macintosh file type code(s): TEXT
Person & email address to contact for further information: Erik
Wilde <erik.wilde@dret.net>
Intended usage: COMMON
Restrictions on usage: none
Author: Erik Wilde <erik.wilde@dret.net>
Change controller: IETF
8.3. Media Type: application/linkset+json
IANA has registered the Internet media type "application/linkset+json" for a linkset encoded as described in Section 4.2 in the "Media Types" registry, following [RFC6838] π
Type name: application
Subtype name: linkset+json
Required parameters: N/A
Optional parameters: profile
Encoding considerations: The encoding considerations of [RFC8259]
apply.
Security considerations: The security considerations of RFC 9264
apply.
Interoperability considerations: The interoperability considerations
of [RFC8259] apply.
Published specification: RFC 9264
Applications that use this media type: This media type is not
specific to any application, as it can be used by any application
that wants to interchange Web Links.
Additional information:
Magic number(s): N/A
File extension(s): JSON documents often use ".json" as the file
extension, and this media type does not propose a specific
extension other than this generic one.
Macintosh file type code(s): TEXT
Person & email address to contact for further information: Erik
Wilde <erik.wilde@dret.net>
Intended usage: COMMON
Restrictions on usage: none
Author: Erik Wilde <erik.wilde@dret.net>
Change controller: IETF
9. Security Considerations π₯
okay this section is seriously important, so read it slowly π The security considerations of Section 7 of [RFC3986] apply here, and so do the ones from Web Linking [RFC8288], unless that part is specifically talking about the risks of exposing info in HTTP header fields.
Links can leak information. If a link exposes something sensitive or private, like a URI, that's a problem π Links can also expose "hidden URIs" that were never meant to be shared openly and might not be well protected. Ideally, none of the URIs in links should be treated as "hidden". If some URIs are only meant for certain users, then technical measures should be in place, so that accidentally exposing them doesn't cause any harm.
For the specific mechanisms in this specification, there are two things to keep in mind π
- The Web Linking model always has an "implicit context", which is the resource of the HTTP interaction. That original context can get lost or change when self-contained link representations get moved around. If the context changes, the meaning of links can change too, especially when they have no explicit anchor or use relative URIs. Applications may choose to ignore links that have no explicit anchor or that use relative URIs when they're exchanged as standalone resources.
- This model supports "third-party links", where one party can provide links whose anchor is another party's resource. Depending on the link semantics and the application context, it's important to check that there's enough trust in that third party to let it provide these links. Applications may choose to treat third-party links differently from cases where a resource and its links come from the same party.
10. References π
10.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005,
<https://www.rfc-editor.org/info/rfc3986>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008,
<https://www.rfc-editor.org/info/rfc5234>.
[RFC5646] Phillips, A., Ed. and M. Davis, Ed., "Tags for Identifying
Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646,
September 2009, <https://www.rfc-editor.org/info/rfc5646>.
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type
Specifications and Registration Procedures", BCP 13,
RFC 6838, DOI 10.17487/RFC6838, January 2013,
<https://www.rfc-editor.org/info/rfc6838>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8187] Reschke, J., "Indicating Character Encoding and Language
for HTTP Header Field Parameters", RFC 8187,
DOI 10.17487/RFC8187, September 2017,
<https://www.rfc-editor.org/info/rfc8187>.
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, RFC 8259,
DOI 10.17487/RFC8259, December 2017,
<https://www.rfc-editor.org/info/rfc8259>.
[RFC8288] Nottingham, M., "Web Linking", RFC 8288,
DOI 10.17487/RFC8288, October 2017,
<https://www.rfc-editor.org/info/rfc8288>.
[RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Semantics", STD 97, RFC 9110,
DOI 10.17487/RFC9110, June 2022,
<https://www.rfc-editor.org/info/rfc9110>.
[W3C.REC-json-ld]
Sporny, M., Ed., Kellogg, G., Ed., and M. Lanthaler, Ed.,
"JSON-LD 1.1: A JSON-based Serialization for Linked Data",
W3C Recommendation REC-json-ld-20140116, July 2020,
<https://www.w3.org/TR/json-ld/>.
10.2. Informative References
[DCMI-TERMS]
Dublin Core Metadata Initiative, "DCMI Metadata Terms",
January 2020, <https://www.dublincore.org/specifications/
dublin-core/dcmi-terms/>.
[RFC5988] Nottingham, M., "Web Linking", RFC 5988,
DOI 10.17487/RFC5988, October 2010,
<https://www.rfc-editor.org/info/rfc5988>.
[RFC6690] Shelby, Z., "Constrained RESTful Environments (CoRE) Link
Format", RFC 6690, DOI 10.17487/RFC6690, August 2012,
<https://www.rfc-editor.org/info/rfc6690>.
[RFC6906] Wilde, E., "The 'profile' Link Relation Type", RFC 6906,
DOI 10.17487/RFC6906, March 2013,
<https://www.rfc-editor.org/info/rfc6906>.
[RFC7284] Lanthaler, M., "The Profile URI Registry", RFC 7284,
DOI 10.17487/RFC7284, June 2014,
<https://www.rfc-editor.org/info/rfc7284>.
[W3C.REC-rdf11-concepts]
Cyganiak, R., Ed., Wood, D., Ed., and M. Lanthaler, Ed.,
"RDF 1.1 Concepts and Abstract Syntax", W3C Consortium
Recommendation REC-rdf11-concepts, February 2014,
<https://www.w3.org/TR/rdf11-concepts/>.
Appendix A. JSON-LD Context β¨
okay so, a set of links written in the JSON serialization from Section 4.2 can be read as RDF triples π§ if you add a JSON-LD context [W3C.REC-json-ld] that maps the JSON keys to matching Linked Data terms. π Per Section 6.1 of [W3C.REC-json-ld], when a server sends a link set rendered as "application/linkset+json" to a user agent, it can say "hey, a JSON-LD context exists!" by putting a link with the relation type "http://www.w3.org/ns/json-ld#context" in the HTTP "Link" header field. π¦ bestie, that's so clean.
Figure 19 shows what the response to an HTTP GET on a link set resource URI looks like, and it shows this discovery trick in action. π It's inspired by the GS1 implementation, and the link set uses relation types from the GS1 vocabulary at <https://www.gs1.org/voc/>, written as HTTP URIs. The vibe is very product-info-page, lowkey iconic. π
HTTP/1.1 200 OK
Date: Mon, 11 Oct 2021 10:48:22 GMT
Server: Apache-Coyote/1.1
Content-Type: application/linkset+json
Link: <https://example.org/contexts/linkset.jsonld>
; rel="http://www.w3.org/ns/json-ld#context"
; type="application/ld+json"
Content-Length: 1532
{
"linkset": [
{
"anchor": "https://id.gs1.org/01/09506000149301",
"https://gs1.org/voc/pip": [
{
"href": "https://example.com/en/defaultPage",
"hreflang": [
"en"
],
"type": "text/html",
"title": "Product information"
},
{
"href": "https://example.com/fr/defaultPage",
"hreflang": [
"fr"
],
"title": "Information produit"
}
],
"https://gs1.org/voc/whatsInTheBox": [
{
"href": "https://example.com/en/packContents/GB",
"hreflang": [
"en"
],
"title": "What's in the box?"
},
{
"href": "https://example.com/fr/packContents/FR",
"hreflang": [
"fr"
],
"title": "Qu'y a-t-il dans la boite?"
},
{
"href": "https://example.com/fr/packContents/CH",
"hreflang": [
"fr"
],
"title": "Qu'y a-t-il dans la boite?"
}
],
"https://gs1.org/voc/relatedVideo": [
{
"href": "https://video.example",
"hreflang": [
"en",
"fr"
],
"title*": [
{
"value": "See it in action!",
"language": "en"
},
{
"value": "Voyez-le en action!",
"language": "fr"
}
]
}
]
}
]
}
Figure 19: Using a typed link to support the discovery of a JSON-
LD context for a linkset
Next, the user agent sends an HTTP GET to the link target of the link with the "http://www.w3.org/ns/json-ld#context" relation type to grab the JSON-LD context. πΈ The response is in Figure 20. This context maps "application/linkset+json" representations of link sets to Dublin Core terms [DCMI-TERMS]. β¨ Also, the "linkset" entry in the context is there to support links with the "linkset" relation type inside link sets. π«Ά
HTTP/1.1 200 OK
Content-Type: application/ld+json
Content-Length: 658
{
"@context": [
{
"@version": 1.1,
"@vocab": "https://gs1.org/voc/",
"anchor": "@id",
"href": "@id",
"linkset": {
"@id": "@graph",
"@context": {
"linkset": "linkset"
}
},
"title": {
"@id": "http://purl.org/dc/terms/title"
},
"title*": {
"@id": "http://purl.org/dc/terms/title"
},
"type": {
"@id": "http://purl.org/dc/terms/format"
}
},
{
"language": "@language",
"value": "@value",
"hreflang": {
"@id": "http://purl.org/dc/terms/language",
"@container": "@set"
}
}
]
}
Figure 20: JSON-LD context mapping to Dublin Core terms
Now the fun part π§: applying the Figure 20 context to the Figure 19 link set turns the "application/linkset+json" link set into an RDF link set. π Figure 21 shows the result in the "text/turtle" RDF serialization.
<https://example.com/en/defaultPage>
<http://purl.org/dc/terms/format>
"text/html" .
<https://example.com/en/defaultPage>
<http://purl.org/dc/terms/language>
"en" .
<https://example.com/en/defaultPage>
<http://purl.org/dc/terms/title>
"Product information" .
<https://example.com/en/packContents/GB>
<http://purl.org/dc/terms/language>
"en" .
<https://example.com/en/packContents/GB>
<http://purl.org/dc/terms/title>
"What's in the box?" .
<https://example.com/fr/defaultPage>
<http://purl.org/dc/terms/language>
"fr" .
<https://example.com/fr/defaultPage>
<http://purl.org/dc/terms/title>
"Information produit" .
<https://example.com/fr/packContents/CH>
<http://purl.org/dc/terms/language>
"fr" .
<https://example.com/fr/packContents/CH>
<http://purl.org/dc/terms/title>
"Qu'y a-t-il dans la boite?" .
<https://example.com/fr/packContents/FR>
<http://purl.org/dc/terms/language>
"fr" .
<https://example.com/fr/packContents/FR>
<http://purl.org/dc/terms/title>
"Qu'y a-t-il dans la boite?" .
<https://id.gs1.org/01/09506000149301>
<https://gs1.org/voc/pip>
<https://example.com/en/defaultPage> .
<https://id.gs1.org/01/09506000149301>
<https://gs1.org/voc/pip>
<https://example.com/fr/defaultPage> .
<https://id.gs1.org/01/09506000149301>
<https://gs1.org/voc/relatedVideo>
<https://video.example> .
<https://id.gs1.org/01/09506000149301>
<https://gs1.org/voc/whatsInTheBox>
<https://example.com/en/packContents/GB> .
<https://id.gs1.org/01/09506000149301>
<https://gs1.org/voc/whatsInTheBox>
<https://example.com/fr/packContents/CH> .
<https://id.gs1.org/01/09506000149301>
<https://gs1.org/voc/whatsInTheBox>
<https://example.com/fr/packContents/FR> .
<https://video.example>
<http://purl.org/dc/terms/language>
"en" .
<https://video.example>
<http://purl.org/dc/terms/language>
"fr" .
<https://video.example>
<http://purl.org/dc/terms/title>
"See it in action!"@en .
<https://video.example>
<http://purl.org/dc/terms/title>
"Voyez-le en action!"@fr .
Figure 21: RDF serialization of the linkset resulting from
applying the JSON-LD context
Acknowledgements
Huge thanks ππ to Phil Archer, Dominique Guinard, Mark Nottingham, Julian Reschke, Rob Sanderson, Stian Soiland-Reyes, Sarven Capadisli, and Addison Phillips for the comments and suggestions. You all are literally the best. π
Authors' Addresses
- Erik Wilde, Axway, Email: erik.wilde@dret.net π¦
- Herbert Van de Sompel, Data Archiving and Networked Services, Email: herbert.van.de.sompel@dans.knaw.nl, URI: https://orcid.org/0000-0002-0715-6126 π
π¦ where this page comes from
- ietf: rfc9264 2022-07
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms