Skip to content

Commit 61f5803

Browse files
authored
Merge pull request #20 from slicknode/feature/field-extension-estimator
Field extension estimator #19
2 parents b6a000c + 0ef07a4 commit 61f5803

File tree

8 files changed

+786
-253
lines changed

8 files changed

+786
-253
lines changed

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ or write your own:
7474
last estimator in the chain for a default value.
7575
* **[`directiveEstimator`](src/estimators/directive/README.md):** Set the complexity via a directive in your
7676
schema definition (for example via GraphQL SDL)
77-
* **[`fieldConfigEstimator`](src/estimators/fieldConfig/README.md):** The field config estimator lets you set a numeric value or a custom estimator
77+
* **[`fieldExtensionsEstimator`](src/estimators/fieldExtensions/README.md):** The field extensions estimator lets you set a numeric value or a custom estimator
78+
function in the field config extensions of your schema.
79+
* **[`fieldConfigEstimator`](src/estimators/fieldConfig/README.md):** (DEPRECATED) The field config estimator lets you set a numeric value or a custom estimator
7880
function in the field config of your schema.
79-
* **[`legacyEstimator`](src/estimators/legacy/README.md):** The legacy estimator implements the logic of previous versions. Can be used
81+
* **[`legacyEstimator`](src/estimators/legacy/README.md):** (DEPRECATED) The legacy estimator implements the logic of previous versions. Can be used
8082
to gradually migrate your codebase to new estimators.
8183
* PRs welcome...
8284

src/estimators/fieldConfig/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import {ComplexityEstimator, ComplexityEstimatorArgs} from '../../QueryComplexity';
22

3+
/**
4+
* @deprecated Use fieldExtensionsEstimator instead
5+
*/
36
export default function (): ComplexityEstimator {
7+
console.warn(
8+
'DEPRECATION WARNING: fieldConfigEstimator is deprecated. Use fieldExtensionsEstimator instead'
9+
);
10+
411
return (args: ComplexityEstimatorArgs) => {
512
// Calculate complexity score
613
if (typeof args.field.complexity === 'number') {
+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Field Extensions Estimator
2+
3+
The `fieldExtensionsEstimator` lets you define a numeric value or a custom estimator
4+
in the field config extensions of your GraphQL schema. If no complexity is set in the field config,
5+
the estimator does not return any value and the next estimator in the chain is executed.
6+
7+
## Usage
8+
9+
```typescript
10+
import queryComplexity, {
11+
fieldExtensionsEstimator,
12+
simpleEstimator
13+
} from 'graphql-query-complexity';
14+
15+
const rule = queryComplexity({
16+
estimators: [
17+
fieldExtensionsEstimator(),
18+
19+
// We use the simpleEstimator as fallback so we only need to
20+
// define the complexity for non 1 values (this is not required...)
21+
simpleEstimator({defaultComplexity: 1})
22+
]
23+
// ... other config
24+
});
25+
```
26+
27+
You can set a custom complexity as a numeric value in the field config:
28+
29+
```javascript
30+
const Post = new GraphQLObjectType({
31+
name: 'Post',
32+
fields: () => ({
33+
title: { type: GraphQLString },
34+
text: {
35+
type: GraphQLString,
36+
extensions: {
37+
complexity: 5
38+
},
39+
},
40+
}),
41+
});
42+
```
43+
44+
**Example Query:**
45+
46+
```graphql
47+
query {
48+
posts(count: 10) {
49+
title
50+
text
51+
}
52+
}
53+
```
54+
55+
This query would result in a complexity of 7.
56+
5 for the `text` field and 1 for each of the other fields.
57+
58+
You can also pass an estimator in the field config to determine a custom complexity.
59+
This function will provide the complexity of the child nodes as well as the field input arguments.
60+
61+
The function signature is the same as for the main estimator which lets you reuse estimators:
62+
63+
```typescript
64+
type ComplexityEstimatorArgs = {
65+
type: GraphQLCompositeType,
66+
field: GraphQLField<any, any>,
67+
args: {[key: string]: any},
68+
childComplexity: number
69+
}
70+
71+
type ComplexityEstimator = (options: ComplexityEstimatorArgs) => number | void;
72+
```
73+
74+
That way you can make a more realistic estimation of individual field complexity values:
75+
76+
```javascript
77+
const Query = new GraphQLObjectType({
78+
name: 'Query',
79+
fields: () => ({
80+
posts: {
81+
type: new GraphQLList(Post),
82+
args: {
83+
count: {
84+
type: GraphQLInt,
85+
defaultValue: 10
86+
}
87+
},
88+
extensions: {
89+
complexity: ({args, childComplexity}) => childComplexity * args.count,
90+
},
91+
},
92+
}),
93+
});
94+
```
95+
96+
This would result in a complexity of 60 since the `childComplexity` of posts (`text` 5, `title` 1) is multiplied by the
97+
number of posts (`args.count`).

0 commit comments

Comments
 (0)