Skip to content

Instantly share code, notes, and snippets.

@robrichard
Last active February 25, 2020 07:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robrichard/f563fd272f65bdbe8742764f1a149b2b to your computer and use it in GitHub Desktop.
Save robrichard/f563fd272f65bdbe8742764f1a149b2b to your computer and use it in GitHub Desktop.
Relay Compatible `@defer` & `@stream`

Using @defer under an array field will return multiple patches. Patches are unique combinations of label and path

{
  items {
    id
    ...frag @defer(label: "my-label")
  }
}

fragment frag on Item {
  title
}

Initial result:

{
  "data": {
    "items": [
      { "id": 1 },
      { "id": 2 },
      { "id": 3 },
    ]
  }
}

Patches:

  • Multiple Patches
{
  "label": "my-label",
  "path": ["items", 0],
  "data": { "title": "chair" }
}
{
  "label": "my-label",
  "path": ["items", 1],
  "data": { "title": "table" }
}
{
  "label": "my-label",
  "path": ["items", 2],
  "data": { "title": "lamp" }
}

Fields that are on both deferred and non-deferred fragments are returned twice.

{
  item {
    title
    ...frag @defer(label: "my-label")
  }
}

fragment frag on Item {
  title
}

Initial result:

{
  "data": {
    "item": {
      "title": "chair"
    }
  }
}

Patch:

{
  "label": "my-label",
  "path": ["item"],
  "data": {
    "title": "chair" 
  }
}

Deferred fields are not returned at all in the initial response. This differs from the Apollo defer implementation, in which deferred fields are returned as null, and must be nullable in the schema.

{
  item {
    id
    ...frag @defer(label: "my-label")
  }
}

fragment frag on Item {
  title
}
  • Deferred field is not present
{
  "data": {
    "item": {
      "id": 1
    }
  }
}

Queries cannot contain the same field with multiple streams (or mix of stream and non-stream) without aliasing.

Not allowed:

query HeroNameQuery {
  hero {
    friends {
      id
    }
    ...FragA
    ...FragB
    
  }
}

fragment FragA on Character {
  friends @stream(label: "nameLabel", initial_count: 1) {
    name
  }
}

fragment FragB on Character {
  friends @stream(label: "appearsInLabel", initial_count: 2)  {
    appearsIn
  }
}

Allowed:

query HeroNameQuery {
  hero {
    friends {
      id
    }
    ...FragA
    ...FragB
    
  }
}

fragment FragA on Character {
  streamFriendsName: friends @stream(label: "nameLabel", initial_count: 1) {
    name
  }
}

fragment FragB on Character {
  streamFriendsAppearsIn: friends @stream(label: "appearsInLabel", initial_count: 2)  {
    appearsIn
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment