🦉
Programming Notes
  • My Programming Notes
  • CKA Exam Preparation
    • Certified Kubernetes Administrator
    • Setup Minikube
    • Network Design Principles
    • Role-Based Access Control (RBAC)
    • Namespace
    • Resource Quota
    • Pod
    • Deployment
    • Deployment: Rollout
    • ConfigMap
    • Service
    • Service: kubectl expose
    • Pod: Resources Management
    • Pod & Container: Quality of Service Class
    • Pod & Container: Probes
    • Limit Range
    • Scaling: Manual
    • Scaling: Horizontal Pod Autoscaler
    • Persistent Volume & Claim
    • Secret
    • Ingress: Routing
    • Ingress: TLS
    • Ingress: Rate Limit
    • Ingress: Basic Auth
    • Ingress: CRD (Custom Resource Definition)
    • Job
    • CronJob
    • Mutli-Node Cluster
  • Golang
    • Generics
    • Context
    • Goroutines and Channels in Go
    • Goroutine: Concurrency vs Parallelism
    • Goroutine: Performance & Tradeoffs
    • JSON: omitzero
  • Rust
    • Arrays & Slices
    • Closures
    • Generics & Traits
    • Iterators
    • Run Code Simultaneously
    • String vs &str
    • Tests
    • Rustlings Exercises
      • Variables
      • Functions
      • If
      • Primitive Types
      • Vectors
      • Move Semantics
      • Structs
      • Enums and Matching Pattern
      • Strings
      • Modules
      • Hashmaps
      • Options
      • Error Handling
      • Generics
      • Traits
      • Lifetimes
      • Tests
      • Iterators
      • Smart Pointers
      • Threads
      • Macros
      • Quiz 1
      • Quiz 2
      • Quiz 3
  • Software Engineering
    • CAP Theorem
    • Circuit Breaker
    • Decoupling
    • GraphQL: Query Caching
    • HMAC Signature
    • Idempotency
    • Monolith VS Microservice
    • OWASP Top 10 2021
    • PCI DSS
    • PostgreSQL: Partitioning
    • PostgreSQL: Replication
    • Protobuf & gRPC
    • Redis: Streams
    • Resource Scaling
    • Signed URL
    • SOLID
    • Stack VS Heap
    • Stateful VS Stateless
  • Site Reliability Engineering
    • Chaos Engineering
    • Distributed Tracing
    • Kubernetes (k8s)
    • SLA, SLO, and SLI Metrics
    • Site Reliability Engineer
  • Others
    • FFMPEG Cheat sheet
Powered by GitBook
On this page
  • Parsed Query Cache
  • APQ: Automatic Persisted Queries
  • How it Works
  • Advantages
  • Difference between APQ and PQ (Persisted Queries)
  • References
  1. Software Engineering

GraphQL: Query Caching

PreviousDecouplingNextHMAC Signature

Last updated 3 months ago

In GraphQL, the query and the parsed query refer to different stages of handling a GraphQL request.

query GetUser {
  user(id: "123") {
    id
    name
    email
  }
}

This is the text or string version of the GraphQL request that a client sends to the server. It is human-readable and typically written in the GraphQL query language.

When server receive the query request, the server then parse it to validate the query with the schema available and add some query enhancement if possible.

Parsed query is a structured data format (usually a tree: ) that represents the query's components (fields, arguments, fragments, etc.).

Example of parsed query representation of above query:

{
  "Operation": "query",
  "Name": "GetUser",
  "SelectionSet": [
    {
      "Field": "user",
      "Arguments": {
        "id": "123"
      },
      "SelectionSet": [
        { "Field": "id" },
        { "Field": "name" },
        { "Field": "email" }
      ]
    }
  ]
}

Parsing is CPU-intensive, so caching the parsed query (AST) speeds up repeated requests by skipping the parsing step.

Parsed Query Cache

The implementation is simple we just need to store the parsed query with key using hashed full query.

In golang gqlgen libraries it has function SetQueryCache which stores the parsed query (AST), so if the same query is sent again, the server can skip the parsing step.

srv.SetQueryCache(lru.New[*ast.QueryDocument](1000))

lru in here is just simple in-memory cache. Because this function accept interface as parameter we can create our own custom cache using redis, etcd or any other caching provider we want for distributed systems.

APQ: Automatic Persisted Queries

APQ optimize the operations clients send to a GraphQL server. Instead of sending the full operation string, the client sends an operation identifier: the unique hash of the operation string.

If hash is not found on a server then client makes a second request to register query hash with original query on a server. In order to enable Automatic Persisted Queries we need to change our client.

How it Works

  • On the first query request:

    • Client sends the full query and hashed query.

    • Server validate the hash.

    • Server caches the query with a unique hash.

    • Execute the Query

  • On subsequent requests:

    • Client sends only the query hash.

    • Server looks up the query from the APQ cache.

    • Execute the Query

Advantages

  • Reduces payload size for repeated queries.

  • Ideal for mobile clients or low-bandwidth environments.

Difference between APQ and PQ (Persisted Queries)

Persisted Queries (PQ) are exclusive list of queries that predefined and stored on the server, and clients only send a query ID to execute them. This list of queries are trusted operations and server can reject any queries request that are not in the list.

This provide better security because client can only execute predefined queries. Usually used for mutable operations.

References

You can find implementation example using golang in .

AST
this guide
https://www.apollographql.com/docs/kotlin/advanced/persisted-queries
https://gqlgen.com/reference/apq/
https://www.apollographql.com/tutorials/caching-in-router/04-automatic-persisted-queries