Skip to content

Commit c680719

Browse files
committed
mention how to implement custom validators
1 parent ac5dd90 commit c680719

File tree

3 files changed

+88
-46
lines changed

3 files changed

+88
-46
lines changed

docs/execution/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ Execution
1010
dataloader
1111
fileuploading
1212
subscriptions
13-
validation
13+
queryvalidation

docs/execution/queryvalidation.rst

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
Query Validation
2+
==========
3+
GraphQL uses query validators to check if Query AST is valid and can be executed. Every GraphQL server implements
4+
standard query validators. For example, there is an validator that tests if queried field exists on queried type, that
5+
makes query fail with "Cannot query field on type" error if it doesn't.
6+
7+
To help with common use cases, graphene provides a few validation rules out of the box.
8+
9+
10+
Depth limit Validator
11+
-----------------
12+
The depth limit validator helps to prevent execution of malicious
13+
queries. It takes in the following arguments.
14+
15+
- ``max_depth`` is the maximum allowed depth for any operation in a GraphQL document.
16+
- ``ignore`` Stops recursive depth checking based on a field name. Either a string or regexp to match the name, or a function that returns a boolean
17+
- ``callback`` Called each time validation runs. Receives an Object which is a map of the depths for each operation.
18+
19+
Example
20+
-------
21+
22+
Here is how you would implement depth-limiting on your schema.
23+
24+
.. code:: python
25+
from graphql import validate, parse
26+
from graphene import ObjectType, Schema, String
27+
from graphene.validation import depth_limit_validator
28+
29+
30+
class MyQuery(ObjectType):
31+
name = String(required=True)
32+
33+
34+
schema = Schema(query=MyQuery)
35+
36+
# Queries which have a depth more than 20
37+
# will not be executed.
38+
39+
validation_errors = validate(
40+
schema=schema,
41+
document_ast=parse('THE QUERY'),
42+
rules=(
43+
depth_limit_validator(
44+
max_depth=20
45+
),
46+
)
47+
)
48+
49+
50+
Implementing custom validators
51+
------------------------------
52+
All custom query validators should extend the `ValidationRule <https://github.com/graphql-python/graphql-core/blob/v3.0.5/src/graphql/validation/rules/__init__.py#L37>`_
53+
base class importable from the graphql.validation.rules module. Query validators are visitor classes. They are
54+
instantiated at the time of query validation with one required argument (context: ASTValidationContext). In order to
55+
perform validation, your validator class should define one or more of enter_* and leave_* methods. For possible
56+
enter/leave items as well as details on function documentation, please see contents of the visitor module. To make
57+
validation fail, you should call validator's report_error method with the instance of GraphQLError describing failure
58+
reason. Here is an example query validator that visits field definitions in GraphQL query and fails query validation
59+
if any of those fields are introspection fields:
60+
61+
.. code:: python
62+
from graphql import GraphQLError
63+
from graphql.language import FieldNode
64+
from graphql.validation import ValidationRule
65+
66+
67+
my_blacklist = (
68+
"disallowed_field",
69+
)
70+
71+
72+
def is_blacklisted_field(field_name: str):
73+
return key.lower() in my_blacklist
74+
75+
76+
class BlackListRule(ValidationRule):
77+
def enter_field(self, node: FieldNode, *_args):
78+
field_name = node.name.value
79+
if not is_blacklisted_field(field_name):
80+
return
81+
82+
self.report_error(
83+
GraphQLError(
84+
f"Cannot query '{field_name}': field is blacklisted.", node,
85+
)
86+
)
87+

docs/execution/validation.rst

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)