graphql / graphql/graphql-spec

Strawman: mention of non-self-describing responses

Open
#1,060 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
14.6k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

I know that the spec is agnostic regarding serialization formats, but I felt the need to share this idea with future readers, since it relates to the JSON format.

Sometimes clients want to achieve the best possible data transfer rate, trading it for processing speed. In the realm of text-based protocols, one of the ways to achieve this is through [compression](https://www.wikiwand.com/en/HTTP_compression). Another is through [deduplication](https://github.com/gajus/graphql-deduplicator) of entities. What I wish to propose is an additional approach to reducing the size of GraphQL responses, which I believe might be worth mentioning in the spec.

The idea is to elide all requested keys from the resulting object and rely on the structure of the GraphQL request to be able to interpret it. In the example presented below, the useful content of the expected response (ignoring whitespace) is composed of keys (46%), values (41%) and other characters (13%). By eliminating the keys, we achieve a reduction of 46% in plain text size and 26% in the gzipped version.

---
Consider this GraphQL query

```graphql
{
hero(episode: $episode) { # 0
name # |-0
heroFriends: friends { # |-1
id # |-0
name # |-1
}
}
}
```

yielding the result (the `data` field)

```json
{
"hero": {
"name": "R2-D2",
"heroFriends": [
{
"id": "1000",
"name": "Luke Skywalker"
},
{
"id": "1002",
"name": null
},
{
"id": "1003",
"name": "Leia Organa"
}
]
}
}
```

that can be transformed with the following `jq` [filter](https://jqplay.org/s/09E55aILAae)

```jq
walk(if type == "object" then [.[]] else . end)
```

producing this equivalent (and less verbose) JSON

```json
[
[
"R2-D2",
[
[
"1000",
"Luke Skywalker"
],
[
"1002",
null
],
[
"1003",
"Leia Organa"
]
]
]
]
```

which can be transformed back with [this filter](https://jqplay.org/s/8IxQpLJ8ysX):

```jq
{
hero: .[0] | {
name: .[0],
heroFriends: [.[1][] | {
id: .[0],
name: .[1]
}]
}
}
```

Note the similarity between this filter and the original query.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.