## 復雜性
> 此章節僅適應于代碼優先模式。
查詢復雜性允許你定義某些字段的復雜程度,并限制**最大復雜性**的查詢。其原理是通過使用一個簡單的數字來定義每個字段的復雜度。通常每個字段的復雜度默認為1。另外,GraphQL 查詢的復雜性計算可以使用所謂的復雜度估算器進行定制。復雜度估算器是一個計算字段復雜度的簡單函數。你可以將任意數量的復雜度估算器添加到規則中,然后一個接一個地執行。第一個返回數字復雜度值的估算器確定該字段的復雜度。
`@nestjs/graphql` 包與 <span style="color:red">graphql-query-complexity</span> 等工具能很好地集成,他們提供了一種基于成本分析的解決方案。有了這個庫,你可以拒絕在你的 GraphQL 服務中執行成本過高的查詢。
### 安裝
要開始使用它,我們首先要安裝它所需要的依賴包。
```bash
$npm install --save graphql-query-complexity
```
### 快速開始
一旦安裝完,我們就可以定義 `ComplexityPlugin` 這個類:
```typescript
import { GraphQLSchemaHost, Plugin } from '@nestjs/graphql';
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) {}
requestDidStart(): GraphQLRequestListener {
const { schema } = this.gqlSchemaHost;
return {
didResolveOperation({ request, document }) {
const complexity = getComplexity({
schema,
operationName: request.operationName,
query: document,
variables: request.variables,
estimators: [
fieldExtensionsEstimator(),
simpleEstimator({ defaultComplexity: 1 }),
],
});
if (complexity >= 20) {
throw new GraphQLError(
`Query is too complex: ${complexity}. Maximum allowed complexity: 20`,
);
}
console.log('Query Complexity:', complexity);
},
};
}
}
```
為了演示,我們將允許的最大復雜度指定為 20。在上面的示例中,我們使用了 2 個估算器,`simpleEstimator` 和 `fieldExtensionsEstimator`。
- `simpleEstimator`:該簡單估算器為每個字段返回一個固定復雜度
- `fieldExtensionsEstimator`:字段擴展估算器提取 schema 中每個字段的復雜度值
> 別忘了將此類添加到任意模塊的提供者數組中。
### 字段級復雜性
有了這個插件,我們可以為任意字段定義復雜度了,做法就是在傳遞給 `@Field()` 裝飾器的選項對象中,指定 `complexity` 屬性的值,如下所示:
```typescript
@Field({ complexity: 3 })
title: string;
```
或者,你也可以定義估算器函數:
```typescript
@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```
### 查詢/變更級復雜性
此外,`@Query` 和 `@Mutation()` 裝飾器也具有復雜性屬性,可以被這樣指定:
```typescript
@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
return this.itemsService.getItems({ count });
}
```
- 介紹
- 概述
- 第一步
- 控制器
- 提供者
- 模塊
- 中間件
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 自定義裝飾器
- 基礎知識
- 自定義提供者
- 異步提供者
- 動態模塊
- 注入作用域
- 循環依賴
- 模塊參考
- 懶加載模塊
- 應用上下文
- 生命周期事件
- 跨平臺
- 測試
- 技術
- 數據庫
- Mongo
- 配置
- 驗證
- 緩存
- 序列化
- 版本控制
- 定時任務
- 隊列
- 日志
- Cookies
- 事件
- 壓縮
- 文件上傳
- 流式處理文件
- HTTP模塊
- Session(會話)
- MVC
- 性能(Fastify)
- 服務器端事件發送
- 安全
- 認證(Authentication)
- 授權(Authorization)
- 加密和散列
- Helmet
- CORS(跨域請求)
- CSRF保護
- 限速
- GraphQL
- 快速開始
- 解析器(resolvers)
- 變更(Mutations)
- 訂閱(Subscriptions)
- 標量(Scalars)
- 指令(directives)
- 接口(Interfaces)
- 聯合類型
- 枚舉(Enums)
- 字段中間件
- 映射類型
- 插件
- 復雜性
- 擴展
- CLI插件
- 生成SDL
- 其他功能
- 聯合服務
- 遷移指南
- Websocket
- 網關
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 適配器
- 微服務
- 概述
- Redis
- MQTT
- NATS
- RabbitMQ
- Kafka
- gRPC
- 自定義傳輸器
- 異常過濾器
- 管道
- 守衛
- 攔截器
- 獨立應用
- Cli
- 概述
- 工作空間
- 庫
- 用法
- 腳本
- Openapi
- 介紹
- 類型和參數
- 操作
- 安全
- 映射類型
- 裝飾器
- CLI插件
- 其他特性
- 遷移指南
- 秘籍
- CRUD 生成器
- 熱重載
- MikroORM
- TypeORM
- Mongoose
- 序列化
- 路由模塊
- Swagger
- 健康檢查
- CQRS
- 文檔
- Prisma
- 靜態服務
- Nest Commander
- 問答
- Serverless
- HTTP 適配器
- 全局路由前綴
- 混合應用
- HTTPS 和多服務器
- 請求生命周期
- 常見錯誤
- 實例
- 遷移指南
- 發現
- 誰在使用Nest?