graphql / graphql/graphql-spec
Strawman: mention of non-self-describing responses
- 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
Assessment
This issue has not been assessed yet.