diff --git a/aiohttp_graphql/graphqlview.py b/aiohttp_graphql/graphqlview.py index 362d87e..e026169 100644 --- a/aiohttp_graphql/graphqlview.py +++ b/aiohttp_graphql/graphqlview.py @@ -1,9 +1,10 @@ from collections import Mapping -from functools import partial +from functools import partial, lru_cache from aiohttp import web from promise import Promise +from graphql import Source, parse, validate from graphql.type.schema import GraphQLSchema from graphql.execution.executors.asyncio import AsyncioExecutor from graphql_server import ( @@ -33,6 +34,7 @@ def __init__( batch=False, jinja_env=None, max_age=86400, + max_cached_queries=128, encoder=None, error_formatter=None, enable_async=True, @@ -52,6 +54,7 @@ def __init__( self.batch = batch self.jinja_env = jinja_env self.max_age = max_age + self.parser = self.get_cached_parser(max_cached_queries) self.encoder = encoder or json_encode self.error_formatter = error_formatter or default_format_error self.enable_async = enable_async and isinstance( @@ -91,6 +94,16 @@ async def parse_body(self, request): return {} + @staticmethod + def get_cached_parser(max_cached_queries): + @lru_cache(maxsize=max_cached_queries) + def cached_parser(query, schema): + source = Source(query, name='GraphQL request') + ast = parse(source) + validation_errors = validate(schema, ast) + return ast, validation_errors + return cached_parser + def render_graphiql(self, params, result): return render_graphiql( jinja_env=self.jinja_env, @@ -140,7 +153,8 @@ async def __call__(self, request): root_value=self.root_value, context_value=self.get_context(request), middleware=self.middleware, - executor=self.executor, + parser=self.parser, + executor=self.executor ) awaited_execution_results = await Promise.all(execution_results) diff --git a/aiohttp_graphql/render_graphiql.py b/aiohttp_graphql/render_graphiql.py index a1eb6f5..70e67df 100644 --- a/aiohttp_graphql/render_graphiql.py +++ b/aiohttp_graphql/render_graphiql.py @@ -4,7 +4,7 @@ from aiohttp import web -GRAPHIQL_VERSION = '0.11.10' +GRAPHIQL_VERSION = '0.11.11' TEMPLATE = '''