8
8
use GraphQL \Error \DebugFlag ;
9
9
use GraphQL \Server \ServerConfig ;
10
10
use GraphQL \Type \Schema ;
11
+ use GraphQL \Validator \DocumentValidator ;
12
+ use GraphQL \Validator \Rules \QueryComplexity ;
13
+ use GraphQL \Validator \Rules \ValidationRule ;
11
14
use Laminas \Diactoros \ResponseFactory ;
12
15
use Laminas \Diactoros \StreamFactory ;
13
16
use Psr \Http \Message \ResponseFactoryInterface ;
21
24
use TheCodingMachine \GraphQLite \Server \PersistedQuery \NotSupportedPersistedQueryLoader ;
22
25
23
26
use function class_exists ;
27
+ use function is_callable ;
24
28
25
29
/**
26
30
* A factory generating a PSR-15 middleware tailored for GraphQLite.
@@ -38,6 +42,9 @@ class Psr15GraphQLMiddlewareBuilder
38
42
39
43
private HttpCodeDeciderInterface $ httpCodeDecider ;
40
44
45
+ /** @var ValidationRule[] */
46
+ private array $ addedValidationRules = [];
47
+
41
48
public function __construct (Schema $ schema )
42
49
{
43
50
$ this ->config = new ServerConfig ();
@@ -97,6 +104,18 @@ public function useAutomaticPersistedQueries(CacheInterface $cache, DateInterval
97
104
return $ this ;
98
105
}
99
106
107
+ public function limitQueryComplexity (int $ complexity ): self
108
+ {
109
+ return $ this ->addValidationRule (new QueryComplexity ($ complexity ));
110
+ }
111
+
112
+ public function addValidationRule (ValidationRule $ rule ): self
113
+ {
114
+ $ this ->addedValidationRules [] = $ rule ;
115
+
116
+ return $ this ;
117
+ }
118
+
100
119
public function createMiddleware (): MiddlewareInterface
101
120
{
102
121
if ($ this ->responseFactory === null && ! class_exists (ResponseFactory::class)) {
@@ -109,6 +128,21 @@ public function createMiddleware(): MiddlewareInterface
109
128
}
110
129
$ this ->streamFactory = $ this ->streamFactory ?: new StreamFactory ();
111
130
131
+ // If getValidationRules() is null in the config, DocumentValidator will default to DocumentValidator::allRules().
132
+ // So if we only added given rule, all of the default rules would not be validated, so we must also provide them.
133
+ $ originalValidationRules = $ this ->config ->getValidationRules () ?? DocumentValidator::allRules ();
134
+
135
+ $ this ->config ->setValidationRules (function (...$ args ) use ($ originalValidationRules ) {
136
+ if (is_callable ($ originalValidationRules )) {
137
+ $ originalValidationRules = $ originalValidationRules (...$ args );
138
+ }
139
+
140
+ return [
141
+ ...$ originalValidationRules ,
142
+ ...$ this ->addedValidationRules ,
143
+ ];
144
+ });
145
+
112
146
return new WebonyxGraphqlMiddleware ($ this ->config , $ this ->responseFactory , $ this ->streamFactory , $ this ->httpCodeDecider , $ this ->url );
113
147
}
114
148
}
0 commit comments