@cungminh2710/graphql-depth-limit

中文文档
1.0.0发布于 2023/01/18MITTypeScriptESM + CJS零依赖近 30 天下载 4014

Limit the complexity of your GraphQL queries based on depth.

原始使用文档
文档目录8 节
  1. Why?
  2. Quantifying Complexity
  3. Here's are some queries with a depth of 0
  4. Deeper queries
  5. Usage
  6. Future Work
  7. Documentation
  8. depthLimit(maxDepth, [options], [callback]) ⇒ function

GraphQL Depth Limit

A fork from GraphQL Depth Limit

Dead-simple defense against unbounded GraphQL queries. Limit the complexity of the queries solely by their depth.

Why?

Suppose you have an Album type that has a list of Songs.

{
  album(id: 42) {
    songs {
      title
      artists
    }
  }
}

And perhaps you have a different entry point for a Song and the type allows you to go back up to the Album.

{
  song(id: 1337) {
    title
    album {
      title
    }
  }
}

That opens your server to the possibility of a cyclical query!

query evil {
  album(id: 42) {
    songs {
      album {
        songs {
          album {
            songs {
              album {
                songs {
                  album {
                    songs {
                      album {
                        songs {
                          album {
                            # and so on...
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

How would your server handle it if the query was 10,000 deep? This may become a very expensive operation, at some point pinning a CPU on the server or perhaps the database. This is a possible DOS vulnerability. We want a way to validate the complexity of incoming queries.

This implementation lets you limit the total depth of each operation.

Quantifying Complexity

Deciding exactly when a GraphQL query is "too complex" is a nuanced and subtle art. It feels a bit like deciding how many grains of sand are needed to compose a "pile of sand". Some other libraries have the developer assign costs to parts of the schema, and adds the cumulative costs for each query.

graphql-validation-complexity does this based on the types, and graphql-query-complexity does it based on each field.

Adding up costs may work for some backends, but it does not always faithfully represent the complexity. By adding the costs at each depth, it's as if the complexity is increasing lineraly with depth. Sometimes the complexity actually increases exponentially with depth, for example if requesting a field means doing another SQL JOIN.

This library validates the total depth of the queries (and mutations).

Here's are some queries with a depth of 0

# simplest possible query
query shallow1 {
  thing1
}

# inline fragments don't actually increase the depth
query shallow2 {
  thing1
  ... on Query {
    thing2
  }
}

# neither do named fragments
query shallow3 {
  ...queryFragment
}

fragment queryFragment on Query {
  thing1
}

Deeper queries

# depth = 1
query deep1_1 {
  viewer {
    name
  }
}

query deep1_2 {
  viewer {
    ... on User {
      name
    }
  }
}

# depth = 2
query deep2 {
  viewer {
    albums {
      title
    }
  }
}

# depth = 3
query deep3 {
  viewer {
    albums {
      ...musicInfo
      songs{
        ...musicInfo
      }
    }
  }
}

fragment musicInfo on Music {
  id
  title
  artists
}

Usage

$ npm install @cungminh2710/graphql-depth-limit

It works with express-graphql and koa-graphql. Here is an example with Express.

import depthLimit from 'graphql-depth-limit'
import express from 'express'
import graphqlHTTP from 'express-graphql'
import schema from './schema'

const app = express()

app.use('/graphql', graphqlHTTP((req, res) => ({
  schema,
  validationRules: [ depthLimit(10) ]
})))

The first argument is the total depth limit. This will throw a validation error for queries (or mutations) with a depth of 11 or more.
The second argument is an options object, where you can do things like specify ignored fields. Introspection fields are ignored by default.
The third argument is a callback which receives an Object which is a map of the depths for each operation.

depthLimit(
  10,
  { ignore: [ /_trusted$/, 'idontcare' ] },
  depths => console.log(depths)
)

Now the evil query from before will tell the client this:

{
  "errors": [
    {
      "message": "'evil' exceeds maximum operation depth of 10",
      "locations": [
        {
          "line": 13,
          "column": 25
        }
      ]
    }
  ]
}

Future Work

  • Type-specific sub-depth limits, e.g. you can only descend 3 levels from an Album type, 5 levels from the User type, etc.
  • More customization options, like custom errors.

Documentation

depthLimit(maxDepth, [options], [callback]) ⇒ function

Creates a validator for the GraphQL query depth

Kind: global function
Returns: function - The validator function for GraphQL validation phase.

ParamTypeDescription
maxDepthNumberThe maximum allowed depth for any operation in a GraphQL document.
[options]Object
options.ignoreString | RegExp | functionStops recursive depth checking based on a field name. Either a string or regexp to match the name, or a function that reaturns a boolean.
[callback]functionCalled each time validation runs. Receives an Object which is a map of the depths for each operation.

版本与发布记录

@cungminh2710/graphql-depth-limit 共发布 1 个版本,首次发布于 2023/01/18;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.0.0latest2023/01/183 年前

关于 @cungminh2710/graphql-depth-limit 的常见问题

@cungminh2710/graphql-depth-limit 是什么?

Limit the complexity of your GraphQL queries based on depth.

如何安装 @cungminh2710/graphql-depth-limit?

在项目目录运行 npm install @cungminh2710/graphql-depth-limit,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:graphql(^16)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cungminh2710/graphql-depth-limit 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cungminh2710/graphql-depth-limit 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cungminh2710/graphql-depth-limit 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=14.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cungminh2710/graphql-depth-limit 可以商用吗?

@cungminh2710/graphql-depth-limit 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cungminh2710/graphql-depth-limit 的下载量有多少?

根据 npm 官方下载统计,@cungminh2710/graphql-depth-limit 在 2026/10/11 – 2026/11/09 这 30 天内被下载 4,014 次,日均约 134 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cungminh2710/graphql-depth-limit 还在维护吗?

最新版本 1.0.0 发布于 2023/01/18(3 年前);至今共发布 1 个版本,其中过去 12 个月发布了 0 个;首次发布于 2023/01/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。