GraphQL 故障排查
Schema 没有生成或实体未出现
现象: GraphQL 架构中缺少某个实体,或实体对应的类型完全没有生成。
原因:
- 实体未启用 GraphQL(
graphql.enabled为false)。 - 全局 GraphQL 被禁用。
- 实体对应的数据库表不存在或数据库用户权限不足。
排查步骤:
- 检查
dab-config.json中该实体的graphql.enabled是否为true。省略时默认true。 - 检查
runtime.graphql.enabled全局开关。 - 查看启动日志中是否有 schema 生成错误。
- 确认数据库表存在,且数据库用户有读取表元数据的权限。
Mutation 返回授权错误
现象: create、update 或 delete mutation 返回授权失败或权限拒绝。
排查步骤:
- 检查实体的
permissions数组——当前角色是否包含所需操作(create、update、delete)。 - 确认请求中的最终角色正确——检查
X-MS-API-ROLE头或 JWT 中的roles。 - 如果只配置了
read,mutation 操作被拒绝是预期行为。 - 使用
dab update添加缺失权限后重启服务。
生产环境中内省被禁用
现象: GraphQL 客户端查询 schema 时返回 Introspection is not allowed。
原因: 生产模式(host.mode: production)下 GraphQL 内省默认被禁用。这是安全设计——防止外部探测完整的 API 架构。
解决: 这是设计使然。如需在特定环境启用,在配置中显式设置 graphql.allow-introspection: true。不建议在生产环境中开启。
关系字段返回 null
现象: 查询实体时关联实体字段返回 null,但数据库中确实存在关联数据。
原因:
- 两个实体之间的
relationships未在配置中定义。 - 关联字段映射错误(
source.fields和target.fields不匹配)。 - 关联的外键列名与数据库实际列名不一致。
排查步骤:
- 确认
dab-config.json中已配置了relationships。 - 确认
source.fields和target.fields中的列名与数据库实际列名完全一致。 - 外键关系是否正确——数据库中是否真的有对应数据。
- 调高日志级别查看启动时是否有关系配置解析错误。
关系名称与实体字段名冲突
现象: 查询某个带关系的实体时返回异常结果或 schema 错误。
原因: 关系名称与同一实体中某个字段名相同。引擎不会验证这种命名冲突,生成的 schema 会产生歧义。
解决: 确保关系名不与任何实体暴露的字段名重复。使用 dab update 重命名关系或重命名字段别名。
变更操作失败
现象: 所有 mutation 操作返回错误。
常见原因与解决:
| 原因 | 解决 |
|---|---|
| SQL Server 连接未启用 MARS | 在连接字符串中添加 MultipleActiveResultSets=True |
| 连接池被禁用 | 确保连接字符串中 Pooling=True(默认) |
roles 声明缺失 | 检查 JWT 令牌是否包含 roles 声明 |
X-MS-API-ROLE 头中角色不存在 | 确认角色名与 permissions 中完全一致 |
多重变更失败
现象: 多重创建(createBooks(items: [...]))失败。
排查步骤:
- 确认
runtime.graphql.multiple-mutations.create.enabled为true(默认false)。 - 多重变更仅 SQL Server 支持。
- 确认所有参与操作的实体都对当前角色有对应的权限。
- 不支持自引用关系的多重创建。
GraphQL 查询返回错误而非空数据
现象: 按主键查询不存在的记录时返回 GraphQL 错误而非空数据。
说明: 这是 GraphQL 的预期行为——book_by_pk(id: 999) 在记录不存在时返回 errors,不像 REST 返回空数组。
