You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
depthLimit:7// defaults to Infinity (ie. no depth limiting)
108
111
});
109
-
```
112
+
```
113
+
114
+
## <aname="lists"></a> Notes on Lists
115
+
116
+
The complexity for list types is not determined by the schema, but by the varibales passed to the field as slicing arguments or by directives
117
+
118
+
1. Slicing arguments: lists must be bounded by one integer slicing argument in order to calculate the comlexity for the field. This package supports the slicing arguments `first`, `last` and `limit`. The complexity of the list will be the value passed as the argument to the field.
119
+
120
+
2. Directives: ... TODO ...
121
+
110
122
111
123
## <aname="how-it-works"></a> How It Works
112
124
113
-
how are things weighted examples
125
+
Rate-limiting is done by IP address.
126
+
127
+
On server start, the GraphQL (GQL) schema is parsed to build an object that maps GQL types/feilds to values corresponding to the weights assigned to each GQL type/field. This object is used internally to cross refernce the fields queried by the user with the weight to apply that field when totaling the overall complexity of the query.
128
+
129
+
For each request, the query is parsed and traversed to total the overall complexity of the query based on the type/field weights configured on setup. This is done statically, before any resolvers are fired, to estimate the upper bound of response size of the request (a proxy for the work done by the server to build the response). The total complexity is then used to allow/block the request based on popular rate-limiting algorithms.
130
+
131
+
If a user sends two request simustaneously, the trailing request will wait for the first one to complete any asyncronous work before being processed.
1. Blocked Requests: blocked requests recieve a response with,
155
+
156
+
- status of `429` for ` Too Many Requests`
157
+
-`Retry-After` header with a value of the time to wait in seconds before the request would be approved (`Infinity` if the complexity is greater than rate-limiting capacity).
158
+
- A JSON response with the `tokens` available, `complexity` of the query, `depth` of the query, `success` of the query set to `false`, and the `timestamp` of the request in ms
159
+
160
+
2. Successful Requests: successful request are passed onto the next function in the middleware chain with the following properties saved to `res.locals`
161
+
162
+
```javascript
163
+
{
164
+
graphglGate: {
165
+
success: boolean, // true
166
+
tokens: number, // tokens available after request
167
+
compexity: number, // complexity of the query
168
+
depth: number, // depth of the query
169
+
timestamp: number, // ms
170
+
}
171
+
}
172
+
```
173
+
174
+
## <aname="error-handling"></a> Error Handling
175
+
176
+
- Incoming queries are validated against the GraphQL schema. If the query is invalid, a response with status code `400` is returned along with the array of GraphQL Validation Errors that were found.
177
+
- To avoid disrupting server activity, errors thrown during the analysis and rate-limiting of the query are logged and the request is passed onto the next middleware function in the chain.
114
178
115
179
## <aname="future-development"></a> Future Development
116
180
117
-
-configure rate-limiting cache with other caching libraries
118
-
- resolve complexity analysis for queries
119
-
- leaky bucket rate-limiting algorithm
181
+
-the ability to use this package with other caching technologies or libraries
182
+
-implement "resolve complexity analysis" for queries
183
+
-implement leaky bucket algorithm for rate-limiting
120
184
- experimint with performance improvments
121
-
- caching optimizations
185
+
- caching optimization
186
+
- ensure connection pagination conventions can be accuratly acconuted for in comprlexity analysis
0 commit comments