- API设计
【免费下载链接】api-guidelines
Microsoft REST API Guidelines
本文基于 Microsoft Graph REST API Guidelines 仓库(graph/articles/deprecation.md)的官方弃用指南,系统讲解在 Microsoft Graph 生态中如何以 OData 标准注解标记已弃用的模型元素、如何通过 HTTP 响应头向客户端传递弃用与移除时间,以及弃用流程与版本化、破坏性变更判定之间的配合关系。读完本文,你将掌握 Revisions 注解五个核心字段的语义与书写规范、注解的可施加对象与级联规则、Deprecation/Sunset 响应头的完整格式,并能独立为一个即将退休的 API 元素设计合规的弃用方案。
弃用的前提:什么时候必须走弃用流程
弃用不是独立动作,而是 API 演进(Versioning)流程的后半段。在 Microsoft Graph REST API Guidelines 的「API contract and nonbackward compatible changes」章节中,官方对变更做了明确分级:
- 非破坏性变更(Non-breaking changes):如新增 nullable 或有默认值的属性、在可演化枚举(evolvable enum)的哨兵成员之后追加成员、改变属性顺序、调整不透明字符串(如资源 ID)的长度或格式等,通常不需要弃用。
- 破坏性变更(Breaking changes):如改变资源 URL 或基本请求/响应、删除/重命名/不兼容地改变已声明属性的类型、删除或重命名 API 及参数、新增必填请求头、为不可演化枚举新增成员、给既有类型新增
Nullable="false"属性、改变顶层错误码、对既有集合引入服务端分页等。
当 API 确实需要引入破坏性变更时,就必须为被替换的旧元素创建新版本,并将旧元素标记为弃用。Microsoft Graph 的版本化做法是:为元素添加一个唯一命名的新版本(优先取自然的新名称,若原名仍最贴切,则在原名后追加_v2后缀),然后用注解把旧版本标记为 deprecated——这正是本文要详细展开的弃用标注机制。
此外,弃用的时间承诺也有硬性约束(见 GuidelinesGraph.md):GA 版本(v1.0 端点)中的 API 一旦被弃用,旧元素必须至少继续支持 36 个月;若能证明无使用量,最短可缩减为 24 个月。beta 端点允许在评估依赖与客户影响后执行破坏性变更与弃用,官方建议先在 beta 端点验证新元素版本,再推广到 GA 端点。
Revisions 注解:弃用的官方标注方式
在 OData 的 CSDL(Common Schema Definition Language)模型中,弃用通过Org.OData.Core.V1.Revisions术语(Term)以注解形式声明。每次弃用需要在一个Record中提供五个字段:
| 字段 | 含义与格式要求 |
|---|---|
Date | 元素被标记为弃用的日期 |
Version | 用于组织 ChangeLog(变更日志),格式为YYYY-MM/Category,其中YYYY-MM是弃用公告所在的月份,Category是该项变更归属的分类 |
Kind | 取值固定为Deprecated(枚举成员Org.OData.Core.V1.RevisionKind/Deprecated) |
Description | 面向人类的变更描述,用于 ChangeLog、文档等处 |
RemovalDate | 元素最早可被移除的日期 |
其中Version字段的设计很关键:它把「弃用公告月份」与「变更分类」绑定在一起,使得 ChangeLog 可以按时间轴与主题分类快速检索某次弃用;RemovalDate则为客户端提供明确的迁移截止线,与前述「GA 至少支持 36 个月(或 24 个月且有非使用证明)」的承诺相互印证。
注解的施加对象与级联规则
该注解可以施加于以下任一元素:
- 类型(Type)
- 实体集(Entity Set)
- 单例(Singleton)
- 属性(Property)
- 导航属性(Navigation Property)
- 函数(Function)
- 动作(Action)
其中存在一条重要的级联规则:如果一个类型被标记为弃用,则该类型的成员(成员属性、导航属性等)无需再逐一标注弃用,对该类型的任何引用也无需额外标注。也就是说,弃用标注应该施加在语义层级最高的位置——弃用了类型,就等于弃用了它所有的成员与使用点,避免冗余注解与不一致。
属性弃用完整示例解析
以下 XML 来自 deprecation.md 的官方示例,展示了如何在实体类型outlookTask上通过Org.OData.Core.V1.Revisions注解完成一次完整弃用声明:
<EntityType Name="outlookTask" BaseType="Microsoft.OutlookServices.outlookItem" ags:IsMaster="true" ags:WorkloadName="Task" ags:EnabledForPassthrough="true"> <Annotation Term="Org.OData.Core.V1.Revisions"> <Collection> <Record> <PropertyValue Property = "Date" Date="2022-03-30"/> <PropertyValue Property = "Version" String="2022-03/Tasks_And_Plans"/> <PropertyValue Property = "Kind" EnumMember="Org.OData.Core.V1.RevisionKind/Deprecated"/> <PropertyValue Property = "Description" String="The Outlook tasks API is deprecated and will stop returning data on June 30, 2024. Please use the new To Do API."/> <PropertyValue Property = "RemovalDate" Date="2024-06-30"/> </Record> </Collection> </Annotation> </EntityType>逐字段对照官方规范:
Date:2022-03-30,即该 API 被正式标记为弃用的日期。Version:2022-03/Tasks_And_Plans,公告月份为 2022 年 3 月,分类为Tasks_And_Plans,ChangeLog 可据此归类检索。Kind:Org.OData.Core.V1.RevisionKind/Deprecated,指明本条修订的性质是弃用。Description:明确告知开发者「Outlook tasks API 已弃用,将于 2024 年 6 月 30 日停止返回数据,请改用新的 To Do API」——好的描述应同时给出弃用事实、停服时间、替代方案三要素。RemovalDate:2024-06-30,即该元素最早可被移除的日期。
注意Revisions术语的值为一个Collection,意味着可以容纳多个Record,同一元素可记录多次修订(例如先标记弃用、后续再补充修订)。
集合属性的侧边并存弃用实战:keyCredentials → keyCredentials_v2
collections.md 第 11.1 节给出了一个在集合属性上应用同一注解的真实场景:当application实体的keyCredentials集合属性需要演化时,模型被更新为「新老两个集合并列」,并把旧属性标记为弃用:
<EntityType Name="application"> <Key> <PropertyRef Name="id" /> </Key> <Property Name="id" Type="Edm.String" Nullable="false" /> <Property Name="keyCredentials" Type="Collection(self.keyCredential)"> <Annotation Term="Org.OData.Core.V1.Revisions"> <Collection> <Record> <PropertyValue Property = "Date" Date="2020-08-20"/> <PropertyValue Property = "Version" String="2020-08/KeyCredentials"/> <PropertyValue Property = "Kind" EnumMember="Org.OData.Core.V1.RevisionKind/Deprecated"/> <PropertyValue Property = "Description" String="keyCredentials has been deprecated. Please use keyCredentials_v2 instead."/> <PropertyValue Property = "RemovalDate" Date="2022-08-20"/> </Record> </Collection> </Annotation> </Property> <NavigationProperty Name="keyCredentials_v2" Type="Collection(self.keyCredential_v2)" ContainsTarget="true" /> </EntityType>这个示例补充了三个重要实践细节:
- 注解直接施加在属性(
Property)上,而_v2新集合被建模为含ContainsTarget="true"的导航属性,使新集合具备独立寻址与删除能力(客户端可用DELETE /applications/{applicationId}/keyCredentials_v2/{keyId}移除单个元素)。 - 在过渡期内,
keyCredentials与keyCredentials_v2被视为同一份数据的两个「视图」,workload 必须保持两者一致,且拒绝在同一请求中同时更新两个集合(返回400 Bad Request)。 RemovalDate(2022-08-20)与Date(2020-08-20)之间恰好相隔两年,符合最短支持期的时间承诺示例。
运行时信号:Deprecation 与 Sunset 响应头
模型注解解决的是「契约层」的声明,而运行时还需要把弃用状态传达给实际调用方。当请求 URL 引用到已弃用的模型元素时,网关(gateway)会在响应中自动追加两个响应头(规范出处:Deprecation Header 草案):
Deprecation头:携带该元素被标记为弃用的日期;Sunset头:携带「弃用日期之后两年」的日期,即预期移除时间。
官方示例如下(见 deprecation.md):
Deprecation: Wed, 30 Mar 2022 11:59:59 GMT Sunset: Thursday, 30 June 2024 23:59:59 GMT Link: https://docs.microsoft.com/en-us/graph/changelog#2022-03-30_name ; rel="deprecation"; type="text/html"; title="name",https://docs.microsoft.com/en-us/graph/changelog#2022-03-30_state ; rel="deprecation"; type="text/html"; title="state"三点解读:
Deprecation头的日期(2022-03-30)与注解中Date字段一致,二者互为印证;Sunset头给出的是「两年后」(此处为 2024-06-30,与注解RemovalDate一致),即服务方承诺的移除时间窗。Link头通过rel="deprecation"语义把客户端引导到 ChangeLog 中对应月份、对应分类的变更条目(#2022-03-30_name、#2022-03-30_state),与注解Version字段的YYYY-MM/Category结构一一对应——这正是Version字段存在的意义:让运行时响应头与文档化 ChangeLog 可互相检索。- 三个头共同构成对客户端的完整通知:何时弃用(Deprecation)、何时失效(Sunset)、去哪里了解细节(Link)。
对比参考:Azure 指南的 azure-deprecating 头
同为微软生态,Azure 的 REST API 指南(第 816 行起「Deprecating Behavior Notification」节)采用了另一种响应头方案:azure-deprecating头以分号分隔的字符串声明「什么将被弃用、何时失效、去哪里了解」,例如:
azure-deprecating: API version 2009-27-07 will retire on 2022-12-01 (https://azure.microsoft.com/updates/video-analyzer-retirement);TLS 1.0 & 1.1 will retire on 2020-10-30 (https://azure.microsoft.com/updates/azure-active-directory-registration-service-is-ending-support-for-tls-10-and-11/)对比可见:Microsoft Graph 采用「注解声明 + Deprecation/Sunset/Link 三头」的结构化方案,弃用日期、移除日期、变更详情链接分别在独立字段/头中表达,便于客户端程序化解析;而 Azure 方案把信息压缩进单一头值的字符串中。设计自己的 API 弃用机制时,可据此权衡结构化与紧凑性。
弃用流程的上下游配套
弃用标注并非孤立机制,它与仓库中多个模式文档协同工作:
- 可演化枚举(evolvable enums):evolvable-enums.md 明确指出,改变
unknownFutureValue哨兵成员的位置属于破坏性变更,必须遵循 弃用流程。枚举的扩展方向是在哨兵之后追加成员,因此正常情况下枚举本身不易触犯弃用;但若确实需要改变哨兵位置或重构枚举成员顺序,则必须走本文所述的 Revisions 注解流程。 - 动作/函数(actions/functions):operations.md 规定,为既有 action/function 新增必填非空参数属于破坏性变更,未经符合弃用指南的版本化处理不允许直接实施——即新增参数要伴随新操作版本,并对旧版本执行弃用标注。
- GA/beta 双端点策略:结合 GuidelinesGraph.md,弃用标注的
Date应选择公告月份,RemovalDate必须满足 GA 端点的 36/24 个月支持承诺;beta 端点则可更灵活地先行验证。
弃用标注自检清单
完成一次合规弃用,建议逐项核对:
- 五字段齐全:
Date、Version(YYYY-MM/Category)、Kind(Deprecated)、Description(含替代方案指引)、RemovalDate均已填写。 - 位置正确:注解施加于类型、实体集、单例、属性、导航属性、函数或动作之一;若类型已弃用,不重复标注其成员与使用点。
- 时间合规:
RemovalDate距Date满足 GA 端点的支持期要求(36 个月,或 24 个月且有非使用证明)。 - 运行时信号就绪:引用弃用元素的请求能收到
Deprecation、Sunset与带rel="deprecation"的Link响应头,且与注解字段一致。 - 替代路径明确:
Description与 ChangeLog(Version分类)指向清晰的新版本/替代 API,客户端可据此平滑迁移。
通过「CSDL 注解 + 运行时响应头 + ChangeLog 分类」三层机制,Microsoft Graph 把 API 弃用从一次突发的破坏性变更,转化为一种可预期、可检索、可程序化感知的标准化生命周期流程——这也是大型 REST 生态管理接口演进的参考范式。
- API设计
【免费下载链接】api-guidelines
Microsoft REST API Guidelines
相关推荐
BaiduPCS-Go 下载只有 100KB/s?三步自查、四步提速,SVIP 限速恢复指南
BaiduPCS Go 下载只有 100KB/s?三步自查、四步提速,SVIP 限速恢复指南 先说你可能遇到的场景:用 BaiduPCS Go 拉一个几十 GB
CLI网络3 步用触控板管理 MacBook 窗口:Loop 窗口管理实操
3 步用触控板管理 MacBook 窗口:Loop 窗口管理实操 你正在 MacBook 上写文档,旁边还开着浏览器、终端和备忘录,几个窗口叠在一块儿。想把浏览
桌面应用Electron.NET 应用生命周期管理:Electron.App API 完整实战指南
Electron.NET 应用生命周期管理:Electron.App API 完整实战指南 导读 Electron.App 是 Electron.NET 中控制
桌面应用跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考