Persisted queries (APQ)
Ship SHA-256 registered queries and optional hardened modes - reduce payload variance and tame public POST surfaces.
Use persisted queries when you want a known query corpus, smaller repeat requests, or tighter control over public GraphQL operations. They reduce payload variance but do not replace authorization or rate limiting.
Clients send extensions.persistedQuery carrying a sha256Hash digest; servers look up hash → GraphQL query text and execute as if the full document shipped.
Quick wiring with grx.NewServer
package main
import (
"log"
"example.com/hello-grx/graph"
"github.com/grx-gql/grx"
)
func main() {
queries := map[string]string{
// Example: SHA-256(lowercase hex) of UTF-8 `query { ping }` via `printf '%s' 'query { ping }' | shasum -a 256`.
"d7b0dfafc61a1f0618f4f346911d5aa87bef97b134f2943383223bdac4410134": `query { ping }`,
}
srv, err := grx.NewServer(
grx.WithSchema(graph.Schema()),
grx.WithPersistedQueries(queries),
)
if err != nil {
log.Fatal(err)
}
_ = srv
}The default HTTP transport matches known digests (case-insensitive hex) and substitutes core.Request text before Execute runs.
Stronger closures - reject anything not APQ‑shaped, verify hash matches inlined body, or full trusted corpus mapping - sit on [server.Config](https://pkg.go.dev/github.com/grx-gql/grx/server#Config) (RequirePersistedQuery, StrictPersistedQueries, TrustedDocuments). Those fields map into the same http decoding path - see Limits → Persisted & trusted corpus.
Companion reading
Treat APQ alongside timeouts, MaxHTTPRequestBytes, and WithDisableIntrospection whenever you tighten a public POST graph endpoint - pair Limits, Introspection, and Security.
See also
- Limits - persisted & trusted corpus
- Automatic persisted query negotiation is not part of the current persisted query guide. Use persisted and trusted documents when the server can define the allowed query corpus.
Last updated on