Optimize views (#1439)

* Optimize execute_graphql_request

* Require operation_ast to be found by view handler

* Remove unused show_graphiql kwarg

* Old style if syntax

* Revert "Remove unused show_graphiql kwarg"

This reverts commit 33b3426092.

* Add missing schema validation step

* Pass args directly to improve clarity

* Remove duplicated operation_ast not None check

---------

Co-authored-by: Firas Kafri <3097061+firaskafri@users.noreply.github.com>
Co-authored-by: Kien Dang <mail@kien.ai>
This commit is contained in:
danthewildcat 2023-10-29 11:42:27 -04:00 committed by GitHub
parent 36cf100e8b
commit e735f5dbdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -9,10 +9,17 @@ from django.shortcuts import render
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import View from django.views.generic import View
from graphql import OperationType, get_operation_ast, parse from graphql import (
ExecutionResult,
OperationType,
execute,
get_operation_ast,
parse,
validate_schema,
)
from graphql.error import GraphQLError from graphql.error import GraphQLError
from graphql.execution import ExecutionResult
from graphql.execution.middleware import MiddlewareManager from graphql.execution.middleware import MiddlewareManager
from graphql.validation import validate
from graphene import Schema from graphene import Schema
from graphene_django.constants import MUTATION_ERRORS_FLAG from graphene_django.constants import MUTATION_ERRORS_FLAG
@ -295,43 +302,56 @@ class GraphQLView(View):
return None return None
raise HttpError(HttpResponseBadRequest("Must provide query string.")) raise HttpError(HttpResponseBadRequest("Must provide query string."))
schema = self.schema.graphql_schema
schema_validation_errors = validate_schema(schema)
if schema_validation_errors:
return ExecutionResult(data=None, errors=schema_validation_errors)
try: try:
document = parse(query) document = parse(query)
except Exception as e: except Exception as e:
return ExecutionResult(errors=[e]) return ExecutionResult(errors=[e])
if request.method.lower() == "get": operation_ast = get_operation_ast(document, operation_name)
operation_ast = get_operation_ast(document, operation_name)
if operation_ast and operation_ast.operation != OperationType.QUERY:
if show_graphiql:
return None
raise HttpError( if (
HttpResponseNotAllowed( request.method.lower() == "get"
["POST"], and operation_ast is not None
"Can only perform a {} operation from a POST request.".format( and operation_ast.operation != OperationType.QUERY
operation_ast.operation.value ):
), if show_graphiql:
) return None
raise HttpError(
HttpResponseNotAllowed(
["POST"],
"Can only perform a {} operation from a POST request.".format(
operation_ast.operation.value
),
) )
try: )
extra_options = {}
if self.execution_context_class:
extra_options["execution_context_class"] = self.execution_context_class
options = { validation_errors = validate(schema, document)
"source": query,
if validation_errors:
return ExecutionResult(data=None, errors=validation_errors)
try:
execute_options = {
"root_value": self.get_root_value(request), "root_value": self.get_root_value(request),
"context_value": self.get_context(request),
"variable_values": variables, "variable_values": variables,
"operation_name": operation_name, "operation_name": operation_name,
"context_value": self.get_context(request),
"middleware": self.get_middleware(request), "middleware": self.get_middleware(request),
} }
options.update(extra_options) if self.execution_context_class:
execute_options[
"execution_context_class"
] = self.execution_context_class
operation_ast = get_operation_ast(document, operation_name)
if ( if (
operation_ast operation_ast is not None
and operation_ast.operation == OperationType.MUTATION and operation_ast.operation == OperationType.MUTATION
and ( and (
graphene_settings.ATOMIC_MUTATIONS is True graphene_settings.ATOMIC_MUTATIONS is True
@ -339,12 +359,12 @@ class GraphQLView(View):
) )
): ):
with transaction.atomic(): with transaction.atomic():
result = self.schema.execute(**options) result = execute(schema, document, **execute_options)
if getattr(request, MUTATION_ERRORS_FLAG, False) is True: if getattr(request, MUTATION_ERRORS_FLAG, False) is True:
transaction.set_rollback(True) transaction.set_rollback(True)
return result return result
return self.schema.execute(**options) return execute(schema, document, **execute_options)
except Exception as e: except Exception as e:
return ExecutionResult(errors=[e]) return ExecutionResult(errors=[e])