Skip to main content
Version: 1.0.0

Customizing Query Stack

Ariadne lets to developers to replace both parsing and validating steps of the query execution stack with custom logic.

Query parser​

Default GraphQL query parser used by Ariadne is the parse function from the graphql-core package:

from graphql import parse

document = parse("{ query string }")

This function takes the str with the GraphQL query, and parsers it into a DocumentNode instance containing the GraphQL AST representation of the query.

Ariadne's GraphQL() ASGI and WSGI apps together with graphql(), graphql_sync() and subscribe() functions accept the query_parser named argument that lets server developers to provide a custom function to use for parsing queries.

If custom parser is set, this parser is called with two arguments:

  • context: ContextValue
  • data: dict[str, Any]: a dict with current operation's payload (query, operationName and variables).

Here's an example custom parser function that only parses the query string from query's payload:

from ariadne.types import ContextValue
from graphql import DocumentNode, parse


def caching_query_parser(context: ContextValue, data: dict[str, Any]) -> DocumentNode:
return parse(data["query"])

Query validation​

Ariadne's GraphQL query validation uses the validate function from the graphql-core package to validate a query against a schema and a set of rules. This function can be swapped out in GraphQL servers using the query_validator option.

Custom validator should have a following signature:

from typing import Collection, Type

from graphql import (
GraphQLSchema,
DocumentNode,
ASTValidationRule,
TypeInfo,
)


def custom_query_validator(
schema: GraphQLSchema,
document_ast: DocumentNode,
rules: Collection[Type[ASTValidationRule]] | None = None,
max_errors: int | None = None,
type_info: TypeInfo | None = None,
) -> list[GraphQLError]:
return [] # List of `GraphQLError`s with problems with the query

Examples​

Caching parsed queries​

Following example shows a custom query parser that caches a number of GraphQL queries using the LRU approach. This parser will raise memory usage of the GraphQL server, but will improve query response times:

from functools import lru_cache

from ariadne.types import ContextValue
from graphql import DocumentNode, parse


parse_cached = lru_cache(maxsize=64)(parse)


def caching_query_parser(context: ContextValue, data: dict[str, Any]) -> DocumentNode:
# Custom parser function is called with the context and entire query's payload.
return parse_cached(data["query"])


# Pass the 'caching_query_parser' to the 'query_parser' option of the 'GraphQL'
graphql = GraphQL(schema, query_parser=caching_query_parser)

Combined parse and validation cache​

The below code combines custom parser and validator functions to add caching to both query parsing and validation parts of the Query Stack:

from collections.abc import Collection
from functools import lru_cache
from typing import Any

from ariadne import make_executable_schema
from ariadne.asgi import GraphQL
from ariadne.graphql import validate_query
from ariadne.types import ContextValue
from graphql import ASTValidationRule, DocumentNode, GraphQLError, GraphQLSchema, TypeInfo, parse


parse_cached = lru_cache(maxsize=64)(parse)


def caching_query_parser(context: ContextValue, data: dict[str, Any]) -> DocumentNode:
# Custom parser function is called with the context and entire query's payload.
return parse_cached(data["query"])


validate_query_cached = lru_cache(maxsize=64)(validate_query)


def caching_query_validator(
schema: GraphQLSchema,
document_ast: DocumentNode,
rules: Collection[type[ASTValidationRule]] | None = None,
max_errors: int | None = None,
type_info: TypeInfo | None = None,
) -> list[GraphQLError]:
return validate_query_cached(
schema=schema,
document_ast=document_ast,
)


# Add type definitions, resolvers, etc...
schema = make_executable_schema("...")

# Using our custom functions for parsing & validation
graphql = GraphQL(
schema,
query_parser=caching_query_parser,
query_validator=caching_query_validator,
)