Skip to main content

generate_cache_key

Function generate_cache_key 

Source
pub fn generate_cache_key(
    query: &str,
    variables: &Value,
    where_clause: Option<&WhereClause>,
    schema_version: &str,
) -> String
Expand description

Generate cache key for query result.

§Security Critical

DIFFERENT VARIABLE VALUES MUST PRODUCE DIFFERENT KEYS to prevent data leakage between users. This function leverages APQ’s security-audited hash_query_with_variables() which correctly handles variable normalization.

§Key Composition

The cache key is a SHA-256 hash of:

SHA256(
  hash_query_with_variables(query, variables) +
  WHERE_clause_structure +
  schema_version
)

This ensures:

  • Same query + variables = same key (cache hit)
  • Different variables = different key (security)
  • Different WHERE clauses = different key (correctness)
  • Schema changes = different key (validity)

§Arguments

  • query - GraphQL query string
  • variables - Query variables from GraphQL request (optional)
  • where_clause - WHERE filter from auto-params (optional)
  • schema_version - Schema hash from CompiledSchema

§Returns

64-character hex string (SHA-256 hash)

§Security Examples

use fraiseql_core::cache::generate_cache_key;
use serde_json::json;

let query = "query getUser($id: ID!) { user(id: $id) { name } }";

// Different users MUST get different cache keys
let alice_key = generate_cache_key(query, &json!({"id": "alice"}), None, "v1");
let bob_key = generate_cache_key(query, &json!({"id": "bob"}), None, "v1");
assert_ne!(alice_key, bob_key, "Security: different variables must produce different keys");

// Same user MUST get same key (determinism)
let alice_key2 = generate_cache_key(query, &json!({"id": "alice"}), None, "v1");
assert_eq!(alice_key, alice_key2, "Determinism: same inputs must produce same key");

§Examples

use fraiseql_core::cache::generate_cache_key;
use fraiseql_core::db::{WhereClause, WhereOperator};
use serde_json::json;

// Simple query with variables
let key = generate_cache_key(
    "query { users(limit: $limit) { id } }",
    &json!({"limit": 10}),
    None,
    "abc123"
);
assert_eq!(key.len(), 64); // SHA-256 hex

// Query with WHERE clause
let where_clause = WhereClause::Field {
    path: vec!["email".to_string()],
    operator: WhereOperator::Icontains,
    value: json!("example.com"),
};

let key_with_where = generate_cache_key(
    "query { users { id } }",
    &json!({}),
    Some(&where_clause),
    "abc123"
);
assert_eq!(key_with_where.len(), 64);