前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库GraphQL deprecated 字段 演进
APAPI 设计GraphQL

GraphQL 如何在不破坏现有客户端的前提下废弃字段?

GraphQL 通过 @deprecated 指令标记字段旧状态,客户端继续可查,服务端按计划移除,实现无版本演进。

前端进阶之旅 · 一题精讲更新于 2026.09.05
API 设计#GraphQL
先看核心答案
理解线索

@deprecated 指令

  1. 标记位置字段定义后加指令并附 reason
  2. 执行语义字段仍正常解析,不改变运行行为
  3. 内省暴露查询 __schema 可见 isDeprecated 和 deprecationReason

@deprecated 仅提供提示,不强制阻断任何客户端

核心回答

先记住这个答案

在 schema 字段上添加 @deprecated(reason: "..."),字段仍保留但内省标记废弃,客户端可获警告。废弃并非删除,直到确认无流量再移除,避免破坏现有查询。

  • 用 @deprecated 标记而非立即删除字段
  • 客户端通过内省或提示感知废弃
  • 移除前需确认无客户端使用该字段

废弃标记与无版本演进的运作机制

GraphQL schema 中的字段通过 @deprecated(reason: "使用 nickname 替代") 指令标记废弃。在 SDL 中,该字段仍存在于类型上,服务端执行器照常处理请求。内省查询时,客户端可获得 deprecationReason 信息,但普通查询不会因此报错。这是非破坏性变更,旧查询继续有效。

无版本演进的核心是每个字段有生命周期:稳定期、废弃期、移除期。废弃期让客户端有时间迁移。服务端一般不主动删除字段,除非通过访问日志或持久化查询分析确认无查询引用。持久化查询(如将查询哈希存储)和访问日志可帮助统计字段使用频率,从而决定是否可安全移除。

用户资料 API 中用户名字段的迁移

假设 User 类型有 name 字段,现需拆为 firstName 和 lastName。增加新字段后,将 name 标为 @deprecated(reason: "使用 firstName 和 lastName")。现有移动客户端仍请求 name,服务端保留映射逻辑,返回拼接值。新客户端改用新字段,内省列表不再显示 name 为推荐字段。

三个月后通过访问日志统计到 name 的查询量降为零,此时从 schema 移除 name。若仍有零星请求,则继续保留。关键是决策基于流量数据,而非时间猜测。没有访问日志的小团队可延长废弃期,或通过客户端版本强制升级。

此策略不适用于的情况与代价

若字段是必填非空(如 String!),废弃但保留没问题。但若移除,某些查询会因字段缺失而校验失败。因此废弃时应同时提供替代字段,否则客户端无法安全迁移,且需预先避免让新客户端依赖废弃字段,不然会陷入无限保留。

另一种失效是客户端缓存了 schema 的内省结果,长期不更新,可能不知道字段已废弃,继续使用。此时只能硬性切断或使用别名兼容。移除字段本身是破坏性变更,应与所有已知客户端确认,不能仅凭内省标记自动处理。

回答前,多想一步

容易答错的地方

把废弃当立即删除
有团队认为加了 @deprecated 就可在下个版本删掉,实际上删除会让现存客户端立刻失败。废弃是一个带明确理由的过渡状态,非删除许可。
忽略 reason 的内容
只写 @deprecated 而不给 reason,开发者不知替代方案。规范中 reason 参数可选,但建议提供明确指引。内省场景下缺少指引会延长迁移时间。
试着用自己的话回答

面试官还会怎么问?

如果客户端不更新,废弃字段能一直保留吗?

可以,但维护成本随字段数量上升。GraphQL 不强制删除,保留它们不影响新字段。长期不迁移者可考虑通过权限或请求头限制旧访问方式。

@deprecated 能用于接口或输入类型吗?

规范支持标记字段和枚举值,不直接标记类型。若要标记整个接口,只能在其所有字段上重复添加指令,或通过注释说明。

是否可在运行时根据客户端版本动态隐藏废弃字段?

不可靠,GraphQL 请求本身不含客户端版本信息。应使用 schema 版本控制或向所有客户端返回 field 存在,由客户端决定。

从一道题,走向一组知识

把知识连起来

GraphQL

GraphQL 中 Enum 适合建模什么,哪些情况应避免使用 Enum?

同属「GraphQL」专题,接着看 GraphQL enum 适用场景 演进 在具体场景中的处理方式。

GraphQL

GraphQL schema 演进中哪些变更属于破坏性变更?

同属「GraphQL」专题,接着看 GraphQL breaking change schema 演进 在具体场景中的处理方式。

参考资料

  • GraphQL Best Practices

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 废弃标记与无版本演进的运作机制
  3. 用户资料 API 中用户名字段的迁移
  4. 此策略不适用于的情况与代价
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑