Overview
When receiving queries from a client, the router takes on the role of a traditional GraphQL server. To reduce the amount of data sent over the network, clients can use APQ to send the router an operation hash in place of the entire operation string.
In this lesson, we will:
- Walk through how the router validates and processes APQ from a client
- Review configuration options for client APQ
APQ from the client
We can mimic a client—such as a frontend app running Apollo Client, which supports APQ—using a curl
command in the terminal.
Let's build out our command. We'll send a new request to our router on http://127.0.0.1:5000
. Next, define a --header
flag with a value of 'content-type: application/json'
.
curl --get http://127.0.0.1:5000 \--header 'content-type: application/json'
We'll also specify two separate instances of --data-urlencode
.
curl --get http://127.0.0.1:5000 \--header 'content-type: application/json' \--data-urlencode # TODO--data-urlencode # TODO
Recall that the first time we send the query to the router, we need to send the actual full-length query string AND its identifier (its SHA-256 hash).
Let's use the first --data-urlencode
flag to pass in our entire query string. We include it in the following format:
--data-urlencode 'query={featuredListings{description id title}}'
To include the hash as part of the second --data-urlencode
flag, we'll define a lengthier string with some additional data. We start by specifying extensions
, and set it equal to an object with a persistedQuery
key. As the value for persistedQuery
, we'll define another object.
--data-urlencode 'extensions={"persistedQuery":{}}'
This next object takes two keys: version
and sha256hash
. We've pre-calculated the SHA-256 hash of the provided query, so you can copy the contents below.
--data-urlencode 'extensions={"persistedQuery":{"version":1,"sha256Hash":"c1a5938ec7ad7707639108ba09ab10ed0b6ae48df0e1826d403ba63649859ff9"}}'
Note: We derived the SHA-256 hash for the query string by passing {featuredListings{description id title}}
exactly (no extra spaces!) into a SHA-256 generator.
Here's what the entire command should look like. Pop open a terminal, and let's run it!
curl --get http://127.0.0.1:5000 \--header 'content-type: application/json' \--data-urlencode 'query={featuredListings{description id title}}' \--data-urlencode 'extensions={"persistedQuery":{"version":1,"sha256Hash":"91c070d387e026c84301ba5d7b500a5647e24de65e9dd9d28f4bebd96cb9c11c"}}'
After just a moment, we'll see the response with our data!
Now let's try it again; this time removing the full query string from our curl
command.
curl --get http://127.0.0.1:5000 \--header 'content-type: application/json' \--data-urlencode 'extensions={"persistedQuery":{"version":1,"sha256Hash":"91c070d387e026c84301ba5d7b500a5647e24de65e9dd9d28f4bebd96cb9c11c"}}'
With this command, we can send just the operation identifier, and our router knows exactly which operation we're talking about. We should see the exact same response in the terminal as before.
Note: We're using a curl
command here to quickly showcase how APQ works in action. To work correctly, the client sending the queries needs logic to generate the identifiers for the APQ, make requests to the router using the hashed queries, and if necessary, retry requests with the full query string and the hash. To read more about configuring this behavior using Apollo Client, check out the Apollo documentation.
Caching client operation APQ
The router enables caching client operation APQ by default. We can further customize how many operations it stores, or even turn off the feature entirely, by setting some flags in our router-config.yaml
file.
apq:router:cache:in_memory:limit: 100
apq:enabled: false
We can also cache our APQ in a distributed cache, which we'll see later on in the course.
Practice
Drag items from this box to the blanks above
SHA-512 hash
is configured by default
the query plan
is not supported
both the query string and its corresponding hash
SHA-256 hash
operation string
must be configured separately
introspection response
Key takeaways
- To support sending the router APQ, a client should implement the logic to convert operation strings to hashes, to send the router these hashes, and to retry the request in the event the router requires the original query string. Apollo Client supports APQ out of the box.
Up next
Receiving queries from clients isn't the router's only job; it must also divide queries between the subgraphs responsible for providing data. In the next lesson, we'll walk through how the router takes on the role of client when sending APQ to subgraphs.
Share your questions and comments about this lesson
This course is currently in
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.