本章仅适用于代码优先方法。
@nestjs/graphql
包与 graphql-query-complexity 等工具集成得很好,这些工具提供了基于成本分析的解决方案。使用这个库,您可以拒绝对 GraphQL 服务器的那些被认为执行成本太高的查询。
安装
要开始使用它,我们首先安装所需的依赖项。
bash
$ npm install --save graphql-query-complexity
入门
安装过程完成后,我们可以定义 ComplexityPlugin
类:
ts
import { GraphQLSchemaHost } from '@nestjs/graphql'
import { Plugin } from '@nestjs/apollo'
import {
ApolloServerPlugin,
GraphQLRequestListener,
} from 'apollo-server-plugin-base'
import { GraphQLError } from 'graphql'
import {
fieldExtensionsEstimator,
getComplexity,
simpleEstimator,
} from 'graphql-query-complexity'
@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
constructor(private gqlSchemaHost: GraphQLSchemaHost) {}
async requestDidStart(): Promise<GraphQLRequestListener> {
const maxComplexity = 20
const { schema } = this.gqlSchemaHost
return {
async didResolveOperation({ request, document }) {
const complexity = getComplexity({
schema,
operationName: request.operationName,
query: document,
variables: request.variables,
estimators: [
fieldExtensionsEstimator(),
simpleEstimator({ defaultComplexity: 1 }),
],
})
if (complexity > maxComplexity) {
throw new GraphQLError(
`Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
)
}
console.log('Query Complexity:', complexity)
},
}
}
}
为了演示目的,我们将允许的最大复杂度指定为20
。在上面的示例中,我们使用了 2 个估算器,即simpleEstimator
和fieldExtensionsEstimator
。
-simpleEstimator
:简单估算器为每个字段返回固定的复杂度
-fieldExtensionsEstimator
:字段扩展估算器提取架构中每个字段的复杂度值
请记住在任何模块中将此类添加到提供程序数组中。
字段级复杂度
使用此插件,我们现在可以通过在传递到@Field()
装饰器的选项对象中指定complexity
属性来定义任何字段的复杂度,如下所示:
ts
@Field({ complexity: 3 })
title: string;
或者,您可以定义估算函数:
ts
@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
Query/Mutation-level complexity
此外,@Query()
和 @Mutation()
装饰器可以指定 complexity
属性,如下所示:
ts
@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
return this.itemsService.getItems({ count });
}