首页
/ Microsoft Graph API 设计模式:Upsert 操作详解

Microsoft Graph API 设计模式:Upsert 操作详解

2025-07-05 06:09:59作者:庞队千Virginia

什么是 Upsert 模式

Upsert 是 Microsoft Graph API 中一种重要的设计模式,它结合了"Update"(更新)和"Insert"(插入)两种操作。这种模式允许开发者通过单一的非破坏性、幂等性操作,使用客户端提供的键值来创建或更新资源。特别适用于基础设施即代码(IaC)场景,确保系统资源能够以可靠、可重复和可控的方式部署。

为什么需要 Upsert 模式

传统 API 的限制

在传统 REST API 设计中:

  1. 创建资源通常使用 POST 方法,由服务端生成主键
  2. 更新资源使用 PATCH 或 PUT 方法
  3. 这两种操作是分开的,且创建操作通常不具备幂等性

基础设施即代码的需求

IaC 实践要求:

  1. 部署脚本可以重复执行而不会产生冲突
  2. 使用声明式方式定义系统资源
  3. 能够使用客户端定义的名称/键值来跟踪资源
  4. 自动化部署过程,减少人为错误

Upsert 实现方案

核心机制

  1. 使用 PATCH 方法:通过客户端提供的键值(主键或备用键)在 URL 中标识资源
  2. 双重行为
    • 资源不存在时:执行创建操作(Insert)
    • 资源存在时:执行更新操作(Update)
  3. 键值处理
    • 自然键:直接作为主键使用
    • 服务生成主键:使用备用键(如 uniqueName)支持幂等创建

备用键设计

  1. 对于 IaC 场景,推荐使用 uniqueName 作为备用键属性名
  2. 备用键必须满足:
    • 设置后不可变
    • 可为 null(用于现有资源的回填)
  3. 服务必须支持通过备用键进行 GET 操作

请求头控制

服务应支持以下请求头来控制 Upsert 行为:

  • If-Match=*:强制作为更新操作处理
  • If-None-Match=*:强制作为创建操作处理
  • Prefer: create-if-missing:向后兼容的显式 Upsert 请求

使用场景与最佳实践

适用场景

  1. 通过 IaC 或期望状态配置管理的资源
  2. 控制平面 API
  3. 管理类或配置类操作

设计建议

  1. 新实体类型应尽可能支持 Upsert 机制
  2. 同时保留传统的 POST 创建方式
  3. 使用 OData 注释标明可 Upsert 的实体集
<EntitySet Name="groups" EntityType="microsoft.graph.group">
  <Annotation Term="Org.OData.Capabilities.V1.UpdateRestrictions">
    <Record>
      <PropertyValue Property="Upsertable" Bool="true"/>
    </Record>
  </Annotation>
</EntitySet>

实际示例分析

实体类型定义

group 实体为例,定义包含:

  • 服务生成的主键 id
  • 客户端提供的备用键 uniqueName
<EntityType Name="group">
  <Key>
    <PropertyRef Name="id"/>
  </Key>
  <Property Name="id" Type="Edm.String"/>
  <Property Name="uniqueName" Type="Edm.String"/>
  <!-- 其他属性 -->
  <Annotation Term="Org.OData.Core.V1.AlternateKeys">
    <!-- 定义备用键 -->
  </Annotation>
</EntityType>

创建路径示例

首次创建 uniqueName 为 "Group157" 的组:

PATCH /groups(uniqueName='Group157')
Content-Type: application/json
Prefer: return=representation

{
    "displayName": "My favorite group",
    "description": "All my favorite people in the world"
}

响应(资源创建):

201 Created
Preference-Applied: return=representation

更新路径示例

相同请求再次执行(资源已存在):

200 OK
Preference-Applied: return=representation

显式 Upsert 请求

向后兼容场景下的显式 Upsert:

PATCH /groups(uniqueName='Group157')
Prefer: create-if-missing; return=representation

注意事项

  1. 向后兼容:现有 API 添加 Upsert 支持时,可能需要 Prefer 头来明确行为
  2. 单例支持:Upsert 也可用于单例资源
  3. PUT 的替代:虽然 PUT 也可实现创建/更新,但不推荐因其具有替换语义
  4. 错误处理:不支持 Upsert 的服务对不存在的资源 PATCH 应返回 404

总结

Upsert 模式为 Microsoft Graph API 提供了一种强大的资源管理机制,特别适合现代云原生和基础设施即代码场景。通过合理设计主键和备用键,结合适当的请求头控制,开发者可以构建出更加健壮、易于维护的自动化部署解决方案。