| Internet-Draft | The Vulcain Protocol | April 2020 |
| Dunglas | Expires 5 October 2020 | [Page] |
This specification defines new HTTP headers (and query parameters) allowing a client to inform the server of the exact data it needs:¶
Preload informs the server that relations of the main requested resource will be necessary.
The server can then reduce the number of round-trips by sending the related resources ahead
of time using HTTP/2 [RFC7540] Server Push. When using Server Push isn't possible (resources
served by a different authority, server not supporting HTTP/2...), the server can hint the
client to fetch those resources as early as possible by using the preload link relation
[W3C.CR-preload-20171026] and the 103 status code [RFC8297].¶
Fields informs the server of the list of fields of the retrieved resources that will be used.
In order to improve performance and reduce bandwidth usage, the server can omit the fields not
requested.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 5 October 2020.¶
Copyright (c) 2020 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) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.¶
The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this document, are to be interpreted as described in [RFC2119].¶
Many formats including HTML [W3C.REC-html52-20171214], JSON-LD [W3C.REC-json-ld-20140116], Atom [RFC4287], XML [W3C.REC-xml-20081126], HAL and JSON:API allow the use of Web Linking [RFC5988] to represent references between resources.¶
The Preload HTTP header allows the client to ask the server to transmit resources linked to the
main resource it will need as soon as possible. To do so, the Preload header MUST contain a
selector [#selectors] referencing links to resources that SHOULD be preloaded.¶
The server MUST recursively follow links referenced by the selector. When a selector traverses
several resources, all the traversed resources SHOULD be sent to the client. If several links
referencing the same resource are selected, this resource MUST be sent at most once.¶
The server MAY limit the number resources that it sends in response to one request.¶
Multiple selectors can be sent by passing multiple Preload HTTP headers.¶
Considering the following resources:¶
/books¶
{
"member": [
"/books/1",
"/books/2"
]
}
¶
/books/1¶
{
"title": "1984",
"author": "/authors/1"
}
¶
/books/2¶
{
"title": "Homage to Catalonia",
"author": "/authors/1"
}
¶
/authors/1¶
{
"givenName": "George",
"familyName": "Orwell"
}
¶
The Preload HTTP header can be used to ask the server to immediately push resources related to the
requested one:¶
GET /books/ HTTP/2 Preload: /member/*/author¶
In addition to /books, the server SHOULD use HTTP/2 Server Push to push the /books/1,
/books/2 and /authors/1 resources. While it is referenced twice, /authors/1 MUST be pushed
only once.¶
Server Push requests generated by the server for related resources MUST include the remaining
selector in a Preload HTTP header. When requesting a pushed relation, the client MUST compute
the remaining selector and pass it in the Preload header.¶
Example:¶
Explicit Request:¶
GET /books/ HTTP/2 Preload: /member/*/author¶
Request to a relation generated by the server (for the push) and the client:¶
GET /books/1 HTTP/2 Preload: /author¶
If it's not possible or beneficial to use HTTP/2 Server Push (reference to a resource not served by
the same authority, client or server not supporting HTTP/2, client having disabled Server Push...),
preload link relations [W3C.CR-preload-20171026] SHOULD be used as a fallback.¶
The server MUST NOT add preload link relations if the related resources are pushed using HTTP/2
Server Push.¶
The Fields HTTP header allows the client to ask the server to return only the specified fields of
the requested resource, and of the preloaded related resources.¶
The Fields HTTP header MUST contain a selector (see #Selector). The server SHOULD return only
the fields matching this selector.¶
Multiple Fields HTTP headers can be passed. All fields matching at least one of these headers
MUST be returned. Other fields of the resource MAY be omitted.¶
Considering the following resources:¶
/books/1¶
{
"title": "1984",
"genre": "novel",
"author": "/authors/1"
}
¶
/authors/1¶
{
"givenName": "George",
"familyName": "Orwell"
}
¶
And the following HTTP request:¶
GET /books/1 HTTP/2 Preload: /author Fields: /author/familyName Fields: /genre¶
The server must return a response containing the following JSON document:¶
{
"genre": "novel",
"author": "/authors/1"
}
¶
And push the following filtered /authors/1 resource:¶
{
"familyName": "Orwell"
}
¶
Server Push requests generated by the server for related resources MUST include the remaining
selector in a Fields HTTP header. When requesting a pushed relation, the client MUST compute the
remaining selector and pass it in the Fields header.¶
Example:¶
Explicit Request:¶
GET /books/ HTTP/2 Fields: /member/*/author¶
Request to a relation generated by the server (for the push) and the client:¶
GET /books/1 HTTP/2 Fields: /author¶
Selectors used as value of the Preload and Fields HTTP headers depend on the Content-Type
of the requested resource. This specification defines default selector formats for common
content-types, and a mechanism to use other selector formats.¶
The client SHOULD use the Accept HTTP header to request the resource in a format compatible with
selectors used in Preload and Fields HTTP headers.¶
The client can use the Prefer HTTP header [RFC7240] with the selector preference to ask the
server to use a specific selector format:¶
GET /books/1 HTTP/2 Accept: text/xml Prefer: selector=css Fields: brand > name¶
If no explicit preferences have been passed, the server MUST assume that the selector format is
the default corresponding to the format of the resource.¶
The following table defines the default selector format for common formats:¶
| Format | Selector format | Identifier |
|---|---|---|
| JSON | Extended JSON Pointer Section 4.1 |
json-pointer
|
| XML | XPath [W3C.REC-xpath-19991116] |
xpath
|
| HTML | CSS selectors [W3C.REC-selectors-3-20181106] |
css
|
The client and the server can negotiate the use of other selector formats using the Prefer HTTP
header.¶
For JSON documents, the default selector format is JSON Pointer [RFC6901]. However, JSON Pointer doesn't provide a mechanism to select entire collections.¶
This specification defines an extension to the JSON Pointer format allowing to select every element
of a collection, the * character.¶
Considering the following JSON document:¶
{
"books": [
{
"title": "1984",
"author": "George Orwell"
},
{
"title": "The Handmaid's Tale",
"author": "Margaret Atwood"
}
]
}
¶
The /books/*/author JSON Pointer selects the author field of every objects in the books array.¶
The * character is escaped by encoding it as the ~2 character sequence.¶
By design, this selector is simple and limited. Simple selectors make it easier to limit the complexity of requests executed by the server.¶
Another option available to clients is to utilize Request URI query-string parameters to pass
preload and fields selectors. The preload and query parameters MAY be used to pass selectors
corresponding respectively to the Preload and Fields HTTP headers. To pass multiple selectors,
parameters can be passed multiple times.¶
Example: /books/1?fields=/title&fields=/author&preload=/author¶
When using query parameters, the server MUST pass the remaining part of the selector as parameter
of the generated link.¶
Example:¶
GET /books/?preload=/member/*/author HTTP/2
{
"member": {
"/books/1?preload=/author",
"/books/1?preload=/author"
}
}
¶
As altering the URI can have undesirable effects, using HTTP headers SHOULD be preferred. Support
for query parameters is OPTIONAL. A server supporting query parameters MUST also support the
corresponding HTTP headers.¶
While using hypermedia capabilities of the HTTP protocol through Web Linking SHOULD always be
preferred, sometimes links between resources are known by the server but are not provided in the
HTTP response.¶
In such cases, the server can compute the link server-side in order to push the
related resource. Such server-side computed links MAY be documented, for instance
by providing an OpenAPI specification containing Link
objects.¶
Considering the following resources and assuming that the server knows that the author field
references the resources /authors/{id} resource:¶
/books/1¶
{
"title": "1984",
"author": 1
}
¶
/authors/1¶
{
"givenName": "George",
"familyName": "Orwell"
}
¶
In response to this request , both /books/1 and /authors/1 should be pushed:¶
GET /books/1 HTTP/2 Preload: /author¶
Using the Preload header can lead to a large number of resources to be generated and pushed. The
server SHOULD limit the maximum number of resources to push. The depth of the selector SHOULD
also be limited by the server.¶
The Preloadand Fields header fields will be added to the "Permanent Message Header Field Names"
registry defined in [RFC3864].¶
A selector registry could also be added.¶