1
1
from collections import Mapping
2
- from functools import partial
2
+ from functools import partial , lru_cache
3
3
4
4
from aiohttp import web
5
5
from promise import Promise
6
6
7
+ from graphql import Source , parse , validate
7
8
from graphql .type .schema import GraphQLSchema
8
9
from graphql .execution .executors .asyncio import AsyncioExecutor
9
10
from graphql_server import (
@@ -33,6 +34,7 @@ def __init__(
33
34
batch = False ,
34
35
jinja_env = None ,
35
36
max_age = 86400 ,
37
+ max_cached_queries = 128 ,
36
38
encoder = None ,
37
39
error_formatter = None ,
38
40
enable_async = True ,
@@ -52,6 +54,7 @@ def __init__(
52
54
self .batch = batch
53
55
self .jinja_env = jinja_env
54
56
self .max_age = max_age
57
+ self .parser = self .get_cached_parser (max_cached_queries )
55
58
self .encoder = encoder or json_encode
56
59
self .error_formatter = error_formatter or default_format_error
57
60
self .enable_async = enable_async and isinstance (
@@ -91,6 +94,16 @@ async def parse_body(self, request):
91
94
92
95
return {}
93
96
97
+ @staticmethod
98
+ def get_cached_parser (max_cached_queries ):
99
+ @lru_cache (maxsize = max_cached_queries )
100
+ def cached_parser (query , schema ):
101
+ source = Source (query , name = 'GraphQL request' )
102
+ ast = parse (source )
103
+ validation_errors = validate (schema , ast )
104
+ return ast , validation_errors
105
+ return cached_parser
106
+
94
107
def render_graphiql (self , params , result ):
95
108
return render_graphiql (
96
109
jinja_env = self .jinja_env ,
@@ -140,7 +153,8 @@ async def __call__(self, request):
140
153
root_value = self .root_value ,
141
154
context_value = self .get_context (request ),
142
155
middleware = self .middleware ,
143
- executor = self .executor ,
156
+ parser = self .parser ,
157
+ executor = self .executor
144
158
)
145
159
146
160
awaited_execution_results = await Promise .all (execution_results )
0 commit comments