使用 Microsoft Graph 的最佳做法
本文介绍可应用的最佳做法,以帮助应用程序充分利用 Microsoft Graph,无论是学习Microsoft Graph、提高应用性能,还是使应用程序对最终用户更可靠。
使用 Graph 浏览器了解 API
开始探索可通过 Microsoft Graph 提供的数据的最简便方法是使用 Graph 浏览器。 通过 Graph 浏览器,你可以手动编写 REST 请求(带有完整的 CRUD 支持)、调整 HTTP 请求头,以及查看数据响应。 为了帮助你入门,Graph 浏览器还提供了一组查询示例。
在将它们集成到应用程序之前,请尝试使用新的 API。
身份验证
若要通过 Microsoft Graph 访问数据,应用程序需要获取 OAuth 2.0 访问令牌,并在以下任一选项中将其呈现给 Microsoft Graph:
- HTTP 授权请求头(作为一个持有者令牌)
- Graph 客户端构造函数(当使用 Microsoft Graph 客户端库时)
使用 Microsoft 身份验证库 (MSAL) 获取Microsoft Graph 的访问令牌。
许可和授权
在应用中适用以下面向许可和授权的最佳做法:
应用最低权限。 仅向用户和应用授予调用 API 所需的最低特权权限。 检查方法主题中的权限部分(例如,请参阅 创建用户),然后选择最小特权权限。 例如,如果应用将只读取当前登录用户的配置文件,请授予User.Read 而不是User.ReadBasic.All。 如果应用不读取用户的日历,请不要向其授予 Calendars.Read 权限。 有关权限的完整列表,请参阅权限引用。
根据应用场景使用正确的权限类型。 避免在同一应用中同时使用应用程序和委派权限。 如果要生成登录用户所在的交互式应用程序,应用程序应使用委派权限。 但是,如果应用程序在没有登录用户(如后台服务或守护程序)的情况下运行,则应用程序应使用应用程序权限。
警告
对交互式方案使用应用程序权限可能会使应用程序面临合规性和安全风险。 它可能会无意中提升用户访问数据的权限,从而绕过管理员配置的策略。
在配置应用时请考虑周全。 这会直接影响最终用户和管理体验,以及应用程序的采用和安全性。 例如:
- 应用程序的名称、徽标、域、发布者验证状态、隐私声明和使用条款显示在同意和其他体验中。 请仔细配置这些设置,以便最终用户能够理解这些设置。
- 考虑谁将同意你的应用程序(终端用户或管理员),并适当将应用程序配置为请求权限。
- 确保了解 静态、动态和增量许可之间的差异。
请考虑多租户应用程序。 预期客户有不同的应用程序和不同状态的同意控件。 例如:
- 租户管理员可以禁用最终用户同意应用程序的功能。 在这种情况下,管理员需要代表他们的用户同意。
- 租户管理员可以设置自定义授权策略,如阻止用户读取其他用户的配置文件,或者将自助服务组创建限制为一组有限用户。 在这种情况下,应用程序应在代表用户执行操作时处理
403 Forbidden
错误响应。
有效处理响应
根据你对 Microsoft Graph 发出的请求,应用程序应准备好处理不同类型的响应。 下面是一些要遵循的最为重要的做法,可确保应用程序能够可靠且可预测地为最终用户运行。
分页
查询资源集合时,由于服务器端页面大小限制,Microsoft Graph会在多个页面中返回结果集。 当结果集跨多个页面时,Microsoft Graph 将在响应中返回 @odata.nextLink
属性,其中包含指向结果下一页的 URL。
例如,列出已登录用户邮件:
GET https://graph.microsoft.com/v1.0/me/messages
如果结果集超过服务器端页面大小限制,将返回包含 @odata.nextLink
属性的响应。
"@odata.nextLink": "https://graph.microsoft.com/v1.0/me/messages?$skip=23"
注意
应用程序在本质上应 始终 处理对响应进行分页的可能性,并在读取结果集的所有页面之前使用 @odata.nextLink
属性获得下一个分页结果集。 最后一页将不包含 @odata.nextLink
属性。 你应在请求的 @odata.nextLink
属性中包括整个 URL,以获取下一页结果,将整个 URL 视为一个不透明的字符串。
有关详细信息,请参阅 分页。
处理预期错误
虽然应用程序应处理所有错误响应(在 400 和 500 范围内),但要特别注意某些预期的错误和响应,如下表所示。
主题 | HTTP 错误代码 | 最佳做法 |
---|---|---|
用户没有访问权限 | 403 | 如果应用程序启动并运行,它可能会遇到此错误,即使它已经通过同意体验获得了必要的权限。 在这种情况下,登录用户很可能没有访问所请求资源的权限。 应用程序应向登录用户反馈通用的“拒绝访问”错误。 |
未找到 | 404 | 在某些情况下,可能无法找到请求的资源。 例如,资源可能不存在,因为它尚未预配 (如用户的照片) 或已被删除。 一些已删除的资源可能在删除后的 30 天内完全恢复(如用户、组和应用程序资源),因此,应用程序也应该考虑到这一点。 |
限制 | 429 | API 可能随时因各种原因而受到限制,因此应用程序必须 始终 准备好处理 429 个响应。 此错误响应包括 HTTP 响应头中的“重试后”字段。 使用“重试后”延迟退出请求是从限制中恢复的最快方法。 有关详细信息,请参阅限制。 |
服务不可用 | 503 | 这可能是因为服务正忙。 应部署类似于 429 的退出策略。 此外,应始终通过新 HTTP 连接发出新的重试请求。 |
处理可演化枚举中的未来成员
在现有的枚举中添加成员会破坏已在使用这些枚举的应用程序。 可演化枚举是 Microsoft Graph API 用来向现有枚举添加新成员的机制,而不会对应用程序造成破坏性改变。
可演化的枚举具有一个名为 unknownFutureValue
的常见 Sentinel 成员,其划分了最初在枚举中已定义的已知成员和随后添加的或将来要定义的未知成员。 在内部,将已知成员映射为小于 sentinel 成员的数值,而未知成员则大于 sentinel 成员。 可演化枚举的文档按照升序列出了可能的字符串值: 已知成员,其次是 unknownFutureValue
,其次是未知成员。 与其他类型的枚举一样,应 始终 通过其 字符串 值引用可演化枚举的成员。
默认情况下,GET 操作仅返回可演化枚举类型属性的已知成员,应用程序只需要处理已知成员。 如果将应用程序设计为处理未知成员,则可以选择使用 HTTP Prefer
请求标头接收这些成员:
Prefer: include-unknown-enum-members
在本地存储数据
理想情况下,应用程序应调用 Microsoft Graph 来根据需要实时检索数据。 仅当特定方案需要,并且该用例在使用条款和隐私策略的涵盖范围内,且不违反 Microsoft API 使用条款 时,才能在本地缓存或存储数据。 应用程序还应该实现适当的保留和删除策略。
优化
一般来说,出于性能甚至是安全或隐私方面的原因,应只获取应用程序真正需要的数据,仅此足矣。
使用投影
只选择应用程序真正需要的属性,仅此即可,因为这样可以在应用程序(和服务中)节省不必要的网络流量和数据处理。
注意
使用 $select
查询参数将查询返回的属性限制为那些应用程序所需的属性。
例如,检索登录用户的邮件时,可以指定仅返回 from 和 subject 属性:
GET https://graph.microsoft.com/v1.0/me/messages?$select=from,subject
在不使用 来限制属性数据量的情况下 $select
发出 GET 请求时,Microsoft Graph 包含 一个 @microsoft.graph.tips 属性,该属性提供与 $select
以下消息类似的最佳做法建议:
"@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET groups?$select=appMetadata,assignedLabels",
获取最少响应
对于某些操作,如 PUT 和 PATCH(在某些情况下还包括 POST),如果应用程序不需要使用响应有效负载,则可以要求 API 返回最小数据。 某些服务已返回 204 No Content
PUT 和 PATCH 操作的响应。
注意
使用 将 “首选” 标头设置为 return=minimal
(如果支持),请求最小表示形式响应。 对于创建操作,使用此标头可能不合适,因为应用程序可能希望在响应中获取为新创建的对象生成的 id
服务。
跟踪更改:增量查询和 webhook 通知
如果应用程序需要了解数据变化,只要你所感兴趣的数据发生更改,就会获得 webhook 通知。 这比简单地定期轮询更有效。
使用 webhook 通知,在数据发生变化时获得推送通知。
如果应用程序需要在本地缓存或存储 Microsoft Graph 数据,并使这些数据保持最新,或者出于其他原因需要跟踪数据变化,则应使用增量查询。 这可避免应用程序过度计算以检索应用程序已有的数据,最大程度地减少网络流量,并降低达到限制阈值的可能性。
使用增量查询以有效保持数据最新。
结合使用 webhook 和增量查询
Webhook 和增量查询通常更好地一起使用,因为如果单独使用增量查询,则需要找出正确的轮询间隔 - 太短,这可能会导致空响应,从而浪费资源,太长,最终可能会产生过时的数据。 如果使用 webhook 通知作为触发增量查询调用的触发器,将会两全其美。
使用 webhook 通知作为触发器以触发增量查询调用。 此外,还应确保应用程序有一个支持轮询阈值,以防触发通知。
批处理
JSON 批处理使你能够通过将多个请求合并为一个单一 JSON 对象优化应用程序。 将各个请求合并到一个单独的批请求中,可以使应用程序不受严重网络延迟的影响,并且可以节省连接资源。
使用 批处理, 其中严重的网络延迟可能会对性能产生重大影响。
可靠性和支持
若要确保可靠性并为应用程序提供支持:
- 使用 TLS 1.3 或 1.2 支持 Microsoft Graph 的所有功能。 从 TLS 1.0 和 1.1 迁移。 有关详细信息,请参阅 在环境中启用对 TLS 1.2 的支持。
- 接受 DNS TTL 并设置连接 TTL 以进行匹配。 这可确保在故障转移情况下的可用性。
- 打开到所有播发 DNS 答案的连接。
- 生成唯一的 GUID 并随每个 Microsoft Graph REST 请求发送。 如果需要报告 Microsoft Graph 的问题,这有助于Microsoft更轻松地调查任何错误。
- 每次向 Microsoft Graph 发出请求时,会生成唯一的 GUID,将其随
client-request-id
HTTP 请求标头发送,并将其记录在应用程序日志中。 - 始终记录
request-id
HTTP 响应标头中的 和Date
。 在 Microsoft Q&A 中或向 Microsoft 支持部门报告问题时,需要上述这些以及client-request-id
。
- 每次向 Microsoft Graph 发出请求时,会生成唯一的 GUID,将其随