Migrate to GraphQL Yoga v5
Automatic Persisted Queries
Automatic Persisted Queries is a protocol for reducing the overhead of sending the same GraphQL documents to the server over and over again. Thus reducing client to server upstream traffic.
Since the upload speed can be the bottleneck from client to server, reducing the payload size can improve the performance especially for huge GraphQL documents.
The GraphQL Yoga’s Automatic Persisted Queries plugin follows the APQ Specification of Apollo.
Automatic Persisted Queries do not provide any security features, the benefit of using them is to reduce network overhead. If you want to avoid executing arbitrary GraphQL operations please use Persisted Operations.
Furthermore, an potential DDOS attacker could spam your GraphQL API with persisted operation registrations, thus completly disable the advantages you would get from APQ and, furthermore, even decrease the performance of your GraphQL API.
Installation
Quick Start
Using Automatic Persisted Queries requires installing a separate package.
yarn add @graphql-yoga/plugin-apq
import { createYoga, createSchema } from 'graphql-yoga'
import { createServer } from 'node:http'
import { useAPQ } from '@graphql-yoga/plugin-apq'
const yoga = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String!
}
`
}),
plugins: [useAPQ()]
})
const server = createServer(yoga)
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
Start your yoga server and send a request for priming the cache (register the operation).
curl -X POST -H 'Content-Type: application/json' http://localhost:4000/graphql \
-d '{"query":"{__typename}","extensions":{"persistedQuery":{"version":1,"sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}}}'
Then afterwards we can send the same payload again, but this time omit the query
field.
curl -X POST -H 'Content-Type: application/json' http://localhost:4000/graphql \
-d '{"extensions":{"persistedQuery":{"version":1,"sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}}}'
Especially for big GraphQL document strings, the subsequent payload can be much smaller.
Client Usage
GraphQL clients such Apollo Client
and Urql
support Automatic Persisted Queries out of the box.
Check the corresponding documentation for more information.
Custom Store
By default all the documents strings are stored in memory with an LRU cache that holds up to 1000 unique entries.
A custom store implementation can be provided via the store
option.
import { createYoga, createSchema } from 'graphql-yoga'
import { createServer } from 'node:http'
import { useAPQ } from '@graphql-yoga/plugin-apq'
// Note: this store grows infinitely, so it is not a good idea to use it in production.
const store: APQStore = new Map()
const yoga = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String!
}
`
}),
plugins: [useAPQ({ store })]
})
const server = createServer(yoga)
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
For external stores the set
and get
properties on the store can also return a Promise
.