Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strawman: mention of non-self-describing responses #1060

Open
dsogari opened this issue Nov 15, 2023 · 0 comments
Open

Strawman: mention of non-self-describing responses #1060

dsogari opened this issue Nov 15, 2023 · 0 comments

Comments

@dsogari
Copy link

dsogari commented Nov 15, 2023

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. Another is through deduplication 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

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

yielding the result (the data field)

{
  "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

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

producing this equivalent (and less verbose) JSON

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

which can be transformed back with this filter:

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

Note the similarity between this filter and the original query.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant