尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Relay Resolvers 字段弃用指南:用 @deprecated 标记客户端状态模式中的废弃字段

Relay Resolvers 字段弃用指南:用 @deprecated 标记客户端状态模式中的废弃字段 Relay Resolvers 字段弃用指南用 deprecated 标记客户端状态模式中的废弃字段【免费下载链接】relayRelay is a JavaScript framework for building>项目地址: https://gitcode.com/gh_mirrors/relay29/relay在 Relay 中GraphQL 允许通过deprecated指令标记字段并附加可读的弃用原因。Relay Resolvers 把这套约定原样带到了客户端数据上在客户端状态模式client state schema中通过 docblock 标签把字段标记为 deprecated 后它们会获得与服务端 GraphQL 模式中废弃字段完全一致的处理。本文将以 relay-resolvers/deprecated 文档 为骨架结合 Relay 编译器 docblock 解析与 Schema 生成源码讲解弃用标注的语法、编辑器表现、Markdown 原因书写约定及其底层实现。为什么要在客户端模式中标记弃用字段Relay Resolvers 允许你在客户端用 TypeScript/Flow 函数为本地字段提供解析逻辑这些字段最终会被编译进客户端扩展的 GraphQL 模式中。随着客户端状态模式不断演进某些 Resolver 字段会逐渐被新方案取代——例如拆分得更细的字段、语义更明确的命名或者被服务端字段所替代。此时如果不加任何标记其他开发者仍会像使用新字段一样使用旧字段导致新代码持续依赖即将被移除的逻辑。deprecated正是为解决这个问题而存在。按照 GraphQL 约定被标记的字段会出现在 IDE 的自动补全与悬停提示中并附带弃用原因从而在编码阶段就引导开发者迁移到替代字段。Relay 官方文档明确指出GraphQL allows you to mark fields asdeprecatedand provide an optional human-readable reason. Relay Resolvers bring this same convention to your client data. By marking fields in your client state schema as deprecated they will receive the same treatment as deprecated fields in your server GraphQL schema.也就是说客户端 Resolver 字段的弃用体验与服务端字段完全对齐开发者在客户端状态模式中标注的deprecated最终会被编译器翻译为真正的 GraphQLdeprecated(reason: ...)指令下文源码部分会给出证据。在编辑器中的呈现方式弃用字段会以两种方式在 Relay 的 VSCode 扩展editor-support 文档中被突出显示自动补全autocomplete与悬停hover弃用字段会在补全列表与悬停卡片中标记为 deprecated编辑器中渲染弃用字段会被渲染为置灰greyed out并加上删除线struck through。这套交互与许多主流 IDE 对服务端 GraphQL 废弃字段的处理一致让开发者无需阅读源码注释即可直观识别应避免使用的字段。值得注意的是Relay 的 VSCode 扩展本身是一个独立发布、独立使用的语言服务插件其仓库源码位于 vscode-extension/src编译侧的语言服务逻辑在 relay-lsp/src。弃用原因请使用 Markdown 书写文档中有这样一条重要约定以:::info提示块呈现GraphQL deprecation reasons are expected to be written in markdown. Relay Resolvers will render these descriptions as markdown in the VSCode extension.即GraphQL 的弃用原因文本按约定应使用 Markdown 书写Relay Resolvers 会在 VSCode 扩展中以 Markdown 形式渲染这些描述。因此写原因时可以放心使用**加粗**、inline code、链接等 Markdown 语法扩展会将其渲染成富文本而不是纯文本。语法deprecated docblock 标签标记字段弃用的方式非常直接在 Resolver 函数上方的 docblock 中添加deprecated标签标签后可以跟可选的文本说明弃用原因。文档中的完整示例/** * RelayResolver Author.fullName: String * * deprecated Google Falsehoods Programmers Believe About Names */ export function fullName(author: AuthorModel): string { return ${author.firstName} ${author.lastName}; }要点拆解RelayResolver Author.fullName: String声明这是一个 Relay Resolver字段名为fullName挂在Author类型上返回类型为Stringdeprecated标签将其下方的 Resolver 字段标记为弃用标签后文本Google Falsehoods Programmers Believe About Names作为可选的人类可读弃用原因直接进入最终 GraphQL 指令的reason参数。无原因的简写形式deprecated也可以不跟任何文本只保留标签本身。仓库中的解析测试夹具relay-resolver-deprecated-no-description.js验证了这种形式当没有提供原因文本时生成的指令只包含deprecated而不带reason参数对应 relay-resolver-deprecated-no-description.expected。与 rootFragment 等标签的组合deprecated可以与其他 Resolver 标签自由组合。例如 relay-resolver-deprecated.js 展示了deprecated与rootFragment同时使用的场景/** * RelayResolver User.favorite_page: Page * rootFragment myRootFragment * deprecated This one is not used any more */ graphql fragment myRootFragment on User { id } 其编译产物见对应的.expected文件可以清晰看到弃用标注最终落地为标准的 GraphQL 指令extend type User { favorite_page: Page relay_resolver(import_name: favorite_page, import_path: /path/to/test/fixture/relay-resolver-deprecated.js, fragment_name: myRootFragment) resolver_source_hash(value: 5a025e60e324c90396402649e1fafb03) deprecated(reason: This one is not used any more) }注意这里deprecated(reason: This one is not used any more)就是客户端弃用标注经过编译器转换后的最终形态与任何服务端 GraphQL 模式中的弃用字段完全同构。源码级实现docblock 标签如何变成 deprecated 指令Relay 编译器使用 Rust 实现了 docblock 的解析与 Schema 生成这一链路对理解弃用机制很有帮助。指令名与参数名的定义在 relay-docblock/src/ir.rs 中定义了弃用指令的名称常量static DEPRECATED_RESOLVER_DIRECTIVE_NAME: LazyLockDirectiveName LazyLock::new(|| DirectiveName(deprecated.intern())); static DEPRECATED_REASON_ARGUMENT_NAME: LazyLockArgumentName LazyLock::new(|| ArgumentName(reason.intern()));其中DEPRECATED_RESOLVER_DIRECTIVE_NAME对应 GraphQL 指令deprecatedDEPRECATED_REASON_ARGUMENT_NAME对应其reason参数。这从源码层面印证了文档所述客户端弃用与服务端 GraphQL 弃用同等待遇。docblock 字段解析docblock 解析层位于 relay-docblock/src/docblock_ir.rs。在构建字段 IR 时AllowedFieldName::DeprecatedField被从待处理字段集合中取出并存入deprecated字段见第 286、326、440 行附近的fields.remove(AllowedFieldName::DeprecatedField)说明deprecated是 docblock 语法层的一等公民标签会被专门识别而不是当作普通文本。生成 GraphQL 指令在 relay-docblock/src/ir.rs 的field_directives中弃用字段被转换为常量指令if let Some(deprecated) self.deprecated() { let span deprecated.key_location().span(); directives.push(ConstantDirective { span, at: dummy_token(span), name: string_key_as_identifier(DEPRECATED_RESOLVER_DIRECTIVE_NAME.0), arguments: deprecated.value().map(|value| { List::generated(vec![string_argument( DEPRECATED_REASON_ARGUMENT_NAME.0, value, )]) }), }) }这段代码的语义非常清晰只要 docblock 中存在deprecated标签就会生成一个名为deprecated的 GraphQL 指令若标签后附有原因文本则将其包装为reason参数。这正是上一节测试夹具产物中deprecated(reason: ...)的来源。同样的逻辑也适用于弱对象Weak Object类型定义在 ir.rs 的WeakObjectIr::type_definition中self.deprecated存在时同样会向类型定义推入deprecated指令说明弃用标注不仅适用于字段也适用于 Resolver 类型本身。测试验证弃用行为有专门的测试夹具覆盖分布在两个测试入口下relay-docblock/tests/to_schema/fixtures验证deprecated标签如何被转换为最终 SDL 中的deprecated(reason: ...)指令relay-docblock/tests/parse/fixtures验证 docblock 解析阶段对deprecated标签的语法识别包括带原因relay-resolver-deprecated.js与不带原因relay-resolver-deprecated-no-description.js两种形式。这些测试由 parse_test.rs 与 to_schema_test.rs 驱动构成了docblock 标签 → IR → GraphQL SDL 指令这条完整链路的自动化回归保障。使用建议综合文档与源码实践中有几点值得注意写清楚弃用原因原因文本最终会成为 GraphQL 模式的一部分直接暴露给 IDE 和下游工具因此应尽量具体最好指明替代字段或迁移方向原因文本使用 MarkdownRelay Resolvers 会在 VSCode 扩展中以 Markdown 渲染原因合理使用格式能显著提升可读性弃用与删除是两回事deprecated只是标记层面的提示不会阻止字段被解析、查询或编译它改变的是开发者在编辑器中的使用体验与模式可维护性尽早开始标注客户端状态模式同样会随时间膨胀从字段过时的第一天就标注弃用比事后追溯更可靠。总结Relay Resolvers 的deprecateddocblock 标签把 GraphQL 的弃用约定完整延伸到了客户端状态模式开发者只需在 Resolver 函数上方加一行deprecated及可选的 Markdown 原因编译器便会将其转换为标准的deprecated(reason: ...)GraphQL 指令VSCode 扩展随后会在自动补全、悬停和编辑器中直观呈现弃用状态。从 relay-docblock 的源码与 测试夹具 可以看到这条链路在编译器中是完整、有测试保障的一等公民能力——它让客户端数据模式与服务端模式在字段生命周期管理上保持了一致的体验。【免费下载链接】relayRelay is a JavaScript framework for building>项目地址: https://gitcode.com/gh_mirrors/relay29/relay创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表