缓存
提供对象的标识符以便客户端构建丰富的缓存
在基于入口端点的 API 中,客户端可以使用 HTTP 缓存来确定两个资源是否相同,从而轻松避免重新获取资源。这些 API 中的 URL 是全局唯一标识符,客户端可以利用它来构建缓存。然而,在 GraphQL 中,没有类似 URL 的基元能够为给定对象提供全局唯一标识符。这里提供为 API 暴露这种标识符以供客户端使用的最佳实践。
全局唯一 ID
一个可行的模式是将一个字段(如 id
)保留为全局唯一标识符。这些文档中使用的示例模式使用此方法:
# { "graphiql": true }
{
starship(id:"3003") {
id
name
}
droid(id:"2001") {
id
name
friends {
id
name
}
}
}
这是向客户端开发人员提供的强大工具。与基于资源的 API 使用 URL 作为全局唯一主键的方式相同,该系统中提供 id
字段作为全局唯一主键。
如果后端使用类似 UUID 的标识符,那么暴露这个全局唯一 ID 可能非常简单!如果后端对于每个对象并未分配全局唯一 ID,则 GraphQL 层可能需要构造此 ID。通常来说,将类型的名称附加到 ID 并将其用作标识符都很简单;服务器可能会通过 base64 编码使该 ID 不透明。
与现有 API 的兼容
为了这一目的而使用 id
字段的一个问题是如何让使用 GraphQL API 的客户端能够与现有的 API 并存。例如,如果我们现有的 API 接受了特定类型的 ID,但是我们的 GraphQL API 使用了全局唯一 ID,那么同时使用两者可能比较棘手。
在这些情况下,GraphQL API 可以在单独的字段中暴露以前的 API 的 ID。这同时带给我们两方面的好处:
- GraphQL 客户端可以继续依靠一致的机制来获取全局唯一 ID。
- 当客户端需要使用我们以前的 API 时也可以从对象中获取
previousApiId
并使用它。
备选方案
虽然全局唯一 ID 在过去已经被证明是一种强大的模式,但它们并不是唯一可以使用的模式,也不适用于每种情况。客户端需要的真正关键功能是为其缓存导出全局唯一标识符的能力。服务器可以导出此 ID 以简化客户端,而客户端同样也可以导出标识符。通常,将对象的类型(通过 __typename
查询)与某些类型唯一标识符相结合就很简单。
另外,如果使用 GraphQL API 替换现有的 API,那么如果 GraphQL 中的其他所有字段都相同,只更换了全局唯一的 id
,这可能会令人困惑。这可能是为什么不选用 id
作为全局唯一字段的另一个原因。