Prefer-Push
Client-initiated Server Push for H2
$expand
{json:api}
Compound Documents$expand
GET /heroes/r2d2?$expand=hero.friends($select=id,name,height) HTTP/1.1
⬇︎
HTTP/1.1 200 OK
Content-Type: application/json
{
"hero": {
"id": "/heroes/r2d2",
"name": "R2-D2",
"height": 1.09,
"friends": [
{ "id": "/heroes/luke-skywalker", "name": "Luke Skywalker", "height": 1.72 },
{ "id": "/heroes/han-solo", "name": "Han Solo", "height": 1.85 },
{ "id": "/heroes/leia-organa", "name": "Leia Organa", "height": 1.54 }
]
}
}
POST /query HTTP/1.1
Content-Type: application/graphql
{
hero {
friends {
id
name
height
}
}
}
➡︎
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"hero": {
"name": "R2-D2",
"friends": [
{
"id": "/heroes/luke-skywalker",
"name": "Luke Skywalker",
"height": 1.72
},
{
"id": "/heroes/han-solo",
"name": "Han Solo",
"height": 1.85
},
…
]
}
}
}
@defer
POST /query HTTP/1.1
Content-Type: application/graphql
{
hero {
friends @defer {
id
name
height
}
}
}
➡︎
HTTP/1.1 200 OK
Content-Type: multipart/mixed; boundary=hero
--hero
Content-Type: application/json
{ "data": { "hero": { "name": "R2-D2", "friends": null }}}
--hero
Content-Type: application/json
{
"path": ["hero", "friends"],
"data" : { "hero": { "id": "/heroes/luke-skywalker", "name": "Luke Skywalker", "height": 1.72 }}
}
--hero
…
--hero--
Prefer-Push
GET /heroes/r2d2 HTTP/2.0
Prefer-Push: hero.friends
⬇
HTTP/2.0 200 OK
{
"hero": {
"name": "R2-D2",
"height": 1.09,
"friends": [
{ "id": "/heroes/luke-skywalker" },
{ "id": "/heroes/han-solo" },
{ "id": "/heroes/leia-organa" }
]
}
}
:path /heroes/luke-skywalker
{
"hero": {
"id": "/heroes/luke-skywalker",
"name": "Luke Skywalker",
"height": 1.72
}
}
:path /heroes/han-solo
{
"hero": {
"id": "/heroes/han-solo",
"name": "Han Solo",
"height": 1.85
}
}
:path /heroes/leia-organa
…
preload
?#push-please
on
HTTP APIs Slack.
Prefer-Push
draft by @evertpPrefer-Push
name is up for discussion)
Prefer: transclude
draft by @inadarei