GraphQL

使用 Strapi 项目中的 GraphQL 端点来获取和改变您的内容。

默认情况下,Strapi 会为您的每种内容类型创建 REST 端点。使用 GraphQL 插件,您将能够添加 GraphQL 端点来获取和改变您的内容。

正在寻找 GraphQL API 文档?

GraphQL API 参考 描述了您可以使用 Strapi 的 GraphQL 插件与您的 API 交互的查询、改变和参数。

用法

要在您的应用程序中开始使用 GraphQL,请先安装插件。为此,请打开您的终端并运行以下命令:

bash
yarn
bash
yarn strapi install graphql

然后,启动您的应用并在 http://localhost:1337/graphql 打开浏览器。您现在应该能够访问 GraphQL Playground,它将帮助您编写 GraphQL 查询和突变。

  • 默认情况下,GraphQL Playground 在开发和暂存环境中均启用,但在生产环境中禁用。将 playgroundAlways 配置选项设置为 true 以在生产环境中启用 GraphQL Playground(请参阅 插件配置文档)。
  • 如果 GraphQL Playground 似乎无法访问,请确保已启用 GraphQL 插件:应将 graphql: true 添加到 config/plugins.js|ts 配置文件中;如果没有,请编辑文件以添加此行(有关更多详细信息,请参阅 插件配置)。

配置

插件配置在 config/plugins.js|ts 文件中定义。此配置文件可以包含一个 graphql.config 对象来定义 GraphQL 插件的特定配置(请参阅 插件配置文档)。

Apollo Server 选项可以使用 graphql.config.apolloServer 配置对象 设置。例如,可以使用 Apollo Server 选项来启用 跟踪功能,该功能由 GraphQL 游乐场支持,用于跟踪查询每个部分的响应时间。从 Apollo Server 版本 3.9 开始,默认缓存选项为 cache: 'bounded'。您可以在 apolloServer 配置中更改它。有关更多信息,请访问 Apollo Server 文档

默认情况下,响应返回的最大项目数限制为 100。可以使用 defaultLimit 配置选项更改此值,但应在仔细考虑后再更改:大型查询可能会导致 DDoS(分布式拒绝服务),并可能导致 Strapi 服务器以及数据库服务器负载异常。

js
./config/plugins.js
js
module.exports = {
  //
  graphql: {
    config: {
      endpoint: '/graphql',
      shadowCRUD: true,
      playgroundAlways: false,
      depthLimit: 7,
      amountLimit: 100,
      apolloServer: {
        tracing: false,
      },
    },
  },
}

Shadow CRUD

为了简化和自动化 GraphQL 模式的构建,我们引入了 Shadow CRUD 功能。它会根据您的模型自动生成类型定义、查询、变异和解析器。

示例:

如果您使用 交互式 strapi generate CLI 或管理面板生成了名为 Document 的 API,则您的模型如下所示:

./src/api/[api-name
json
{
  "kind": "collectionType",
  "collectionName": "documents",
  "info": {
    "singularName": "document",
    "pluralName": "documents",
    "displayName": "document",
    "name": "document"
  },
  "options": {
    "draftAndPublish": true
  },
  "pluginOptions": {},
  "attributes": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": "richtext"
    },
    "locked": {
      "type": "boolean"
    }
  }
}
生成的 GraphQL 类型和查询
详情

自定义

Strapi 提供了一个编程 API 来自定义 GraphQL,它允许:

GraphQL 自定义示例
详情

禁用 Shadow CRUD 中的操作

GraphQL 插件提供的 extension 服务 公开了可用于禁用 Content-Type 操作的函数:

Content-type 函数说明参数类型可能的参数值
disable()完全禁用 Content-Type--
disableQueries()仅禁用 Content-Type 的查询--
disableMutations()仅禁用 Content-Type 的突变--
disableAction()禁用 Content-Type 的特定操作字符串列表中的一个值:
  • create
  • find
  • findOne
  • update
  • delete
disableActions()禁用 Content-Type 的特定操作字符串数组列表中的多个值:
  • create
  • find
  • findOne
  • update
  • delete

还可以在字段级别禁用操作,使用以下函数:

字段函数说明
disable()完全禁用字段
disableOutput()禁用字段上的输出
disableInput()禁用字段上的输入
disableFilters()禁用字段上的过滤器输入

例子:

js
// 禁用“restaurant”API 中“restaurant”内容类型的“find”操作
strapi
  .plugin('graphql')
  .service('extension')
  .shadowCRUD('api::restaurant.restaurant')
  .disableAction('find')

// 禁用“document”API 中“document”内容类型的“name”字段
strapi
  .plugin('graphql')
  .service('extension')
  .shadowCRUD('api::document.document')
  .field('name')
  .disable()

使用 getter

以下 getter 可用于检索有关内容类型上允许的操作的信息:

内容类型 getter说明参数类型可能的参数值
isEnabled()返回内容类型是否已启用--
isDisabled()返回内容类型是否已禁用--
areQueriesEnabled()返回内容类型上是否启用查询--
areQueriesDisabled()返回内容类型上是否禁用查询--
areMutationsEnabled()返回内容类型上是否启用突变--
areMutationsDisabled()返回内容类型上是否禁用突变--
isActionEnabled(action)返回所传递的 action 是否在内容类型上启用字符串列表中的一个值:
  • create
  • find
  • findOne
  • update
  • delete
isActionDisabled(action)返回所传递的 action 是否在内容类型上禁用字符串列表中的一个值:
  • create
  • find
  • findOne
  • update
  • delete

以下 getter 可用于检索有关字段上允许的操作的信息:

字段 getter说明
isEnabled()返回字段是否已启用
isDisabled()返回字段是否被禁用
hasInputEnabled()返回字段是否启用了输入
hasOutputEnabled()返回字段是否启用了输出
hasFiltersEnabled()返回字段是否启用了过滤

扩展架构

可以通过注册扩展来扩展 Content API 生成的架构。

此扩展定义为对象或返回对象的函数,将由 GraphQL 插件提供的 extension 服务 公开的 use() 函数使用。

描述扩展的对象接受以下参数:

参数类型描述
typesArray允许使用基于 Nexus 的类型定义扩展架构类型
typeDefsString允许使用 GraphQL SDL 扩展架构类型
pluginsArray允许使用 Nexus 插件 扩展架构
resolvers对象定义自定义解析器
resolversConfig对象定义 解析器的配置选项,例如 authorizationpoliciesmiddlewares

typesplugins 参数基于 Nexus。要使用它们,请将扩展注册为以 nexus 作为参数的函数:

js
./src/index.js
js
module.exports = {
  register({ strapi }) {
    const extension = ({ nexus }) => ({
      types: [
        nexus.objectType({
          // ...
        }),
      ],
      plugins: [
        nexus.plugin({
        // ...
        })
      ]
    })

    strapi.plugin('graphql').service('extension').use(extension)
  }
}

解析器的自定义配置

解析器是 GraphQL 查询或突变处理程序(即为 GraphQL 查询或突变生成响应的函数或函数集合)。每个字段都有一个默认解析器。

扩展 GraphQL 架构 时,resolversConfig 键可用于定义解析器的自定义配置,其中可以包括:

授权配置

默认情况下,GraphQL 请求的授权由已注册的授权策略处理,该策略可以是 API 令牌 或通过 用户和权限插件。用户和权限插件提供更精细的控制。

使用用户和权限插件进行授权
详情

要更改授权配置方式,请使用在 resolversConfig.[MyResolverName] 中定义的解析器配置。可以配置授权:

  • 使用 auth: false 完全绕过授权系统并允许所有请求,
  • 或使用 scope 属性,该属性接受字符串数组来定义授权请求所需的权限。
授权配置示例
详情
策略

策略 可通过 resolversConfig.[MyResolverName].policies 键应用于 GraphQL 解析器。

policies 键是一个接受策略列表的数组,此列表中的每个项目要么是对已注册策略的引用,要么是直接传递的实现(请参阅 策略配置文档)。

直接在 resolversConfig 中实现的策略是将 context 对象和 strapi 实例作为参数的函数。 context 对象允许访问:

  • GraphQL 解析器的 parentargscontextinfo 参数,
  • Koa 的 contextcontext.http 以及 statecontext.state
应用于解析器的 GraphQL 策略示例
详情
Middlewares

中间件 可通过 resolversConfig.[MyResolverName].middlewares 键应用于 GraphQL 解析器。GraphQL 和 REST 实现之间的唯一区别是 config 键变为 options

middlewares 键是一个接受中间件列表的数组,此列表中的每个项目要么是对已注册中间件的引用,要么是直接传递的实现(请参阅 中间件配置文档)。

直接在 resolversConfig 中实现的中间件可以将 GraphQL 解析器的 parentargscontextinfo 对象 作为参数。

带有 GraphQL 的中间件甚至可以作用于嵌套解析器,这比 REST 提供了更精细的控制。

应用于解析器的 GraphQL 中间件示例
详情

与用户和权限插件一起使用

用户和权限插件 是一个可选插件,允许使用完整的身份验证过程保护 API。

注册

通常,您需要先注册或登记,然后才能被识别为用户,然后执行授权请求。

Mutation
graphql
mutation {
  register(input: { username: "username", email: "email", password: "password" }) {
    jwt
    user {
      username
      email
    }
  }
}

您应该会看到在 Strapi 管理面板中的“用户”集合类型中创建了一个新用户。

身份验证

要执行授权请求,您必须首先获取 JWT:

Mutation
graphql
mutation {
  login(input: { identifier: "email", password: "password" }) {
    jwt
  }
}

然后在每个请求中,以 { "Authorization": "Bearer YOUR_JWT_GOES_HERE" } 的形式发送 Authorization 标头。这可以在 GraphQL Playground 的 HTTP Headers 部分中设置。

API 令牌

要使用 API 令牌进行身份验证,请使用 Bearer your-api-token 格式在 Authorization 标头中传递令牌。

在 GraphQL Playground 中使用 API 令牌需要在 HTTP HEADERS 选项卡中添加带有令牌的授权标头:

http
{
"Authorization" : "Bearer <TOKEN>"
}

<TOKEN> 替换为在 Strapi 管理面板中生成的 API 令牌。

安全性

GraphQL 是一种查询语言,允许用户使用比传统 REST API 更广泛的输入面板。 GraphQL API 本质上容易受到安全风险的影响,例如凭据泄露和拒绝服务攻击,可以通过采取适当的预防措施来减少这些风险。

在生产环境中禁用 Playground

在生产环境中,建议禁用 GraphQL Playground。

如果您尚未编辑 配置文件,则默认情况下它在生产中已禁用。

限制最大深度和复杂性

恶意用户可能会发送深度非常大的查询,这可能会使您的服务器过载。使用 depthLimit 配置参数 来限制可以在单个请求中查询的最大嵌套字段数。默认情况下,depthLimit 设置为 10,但在测试和开发期间可以设置为更高的值。

为了进一步提高 GraphQL 的安全性,可以使用第三方工具。请参阅论坛上有关 使用 GraphQL Armor 和 Strapi 的指南。