Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Field extension estimator #19 #20

Merged
merged 2 commits into from
Oct 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ or write your own:
last estimator in the chain for a default value.
* **[`directiveEstimator`](src/estimators/directive/README.md):** Set the complexity via a directive in your
schema definition (for example via GraphQL SDL)
* **[`fieldConfigEstimator`](src/estimators/fieldConfig/README.md):** The field config estimator lets you set a numeric value or a custom estimator
* **[`fieldExtensionsEstimator`](src/estimators/fieldExtensions/README.md):** The field extensions estimator lets you set a numeric value or a custom estimator
function in the field config extensions of your schema.
* **[`fieldConfigEstimator`](src/estimators/fieldConfig/README.md):** (DEPRECATED) The field config estimator lets you set a numeric value or a custom estimator
function in the field config of your schema.
* **[`legacyEstimator`](src/estimators/legacy/README.md):** The legacy estimator implements the logic of previous versions. Can be used
* **[`legacyEstimator`](src/estimators/legacy/README.md):** (DEPRECATED) The legacy estimator implements the logic of previous versions. Can be used
to gradually migrate your codebase to new estimators.
* PRs welcome...

Expand Down
7 changes: 7 additions & 0 deletions src/estimators/fieldConfig/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import {ComplexityEstimator, ComplexityEstimatorArgs} from '../../QueryComplexity';

/**
* @deprecated Use fieldExtensionsEstimator instead
*/
export default function (): ComplexityEstimator {
console.warn(
'DEPRECATION WARNING: fieldConfigEstimator is deprecated. Use fieldExtensionsEstimator instead'
);

return (args: ComplexityEstimatorArgs) => {
// Calculate complexity score
if (typeof args.field.complexity === 'number') {
Expand Down
97 changes: 97 additions & 0 deletions src/estimators/fieldExtensions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Field Extensions Estimator

The `fieldExtensionsEstimator` lets you define a numeric value or a custom estimator
in the field config extensions of your GraphQL schema. If no complexity is set in the field config,
the estimator does not return any value and the next estimator in the chain is executed.

## Usage

```typescript
import queryComplexity, {
fieldExtensionsEstimator,
simpleEstimator
} from 'graphql-query-complexity';

const rule = queryComplexity({
estimators: [
fieldExtensionsEstimator(),

// We use the simpleEstimator as fallback so we only need to
// define the complexity for non 1 values (this is not required...)
simpleEstimator({defaultComplexity: 1})
]
// ... other config
});
```

You can set a custom complexity as a numeric value in the field config:

```javascript
const Post = new GraphQLObjectType({
name: 'Post',
fields: () => ({
title: { type: GraphQLString },
text: {
type: GraphQLString,
extensions: {
complexity: 5
},
},
}),
});
```

**Example Query:**

```graphql
query {
posts(count: 10) {
title
text
}
}
```

This query would result in a complexity of 7.
5 for the `text` field and 1 for each of the other fields.

You can also pass an estimator in the field config to determine a custom complexity.
This function will provide the complexity of the child nodes as well as the field input arguments.

The function signature is the same as for the main estimator which lets you reuse estimators:

```typescript
type ComplexityEstimatorArgs = {
type: GraphQLCompositeType,
field: GraphQLField<any, any>,
args: {[key: string]: any},
childComplexity: number
}

type ComplexityEstimator = (options: ComplexityEstimatorArgs) => number | void;
```

That way you can make a more realistic estimation of individual field complexity values:

```javascript
const Query = new GraphQLObjectType({
name: 'Query',
fields: () => ({
posts: {
type: new GraphQLList(Post),
args: {
count: {
type: GraphQLInt,
defaultValue: 10
}
},
extensions: {
complexity: ({args, childComplexity}) => childComplexity * args.count,
},
},
}),
});
```

This would result in a complexity of 60 since the `childComplexity` of posts (`text` 5, `title` 1) is multiplied by the
number of posts (`args.count`).