在 API 工艺的世界里,没有比设计更受热议的领域了。从 REST、gRPC 到 GraphQL,有许多方法可以设计和标准化 Web API 交互。今天,我们将注意力转向另一种方法,JSON API,JSONAPI.org 上详细介绍的用于构建 API 的规范。
JSONAPI.org 中描述的 JSON API 非常适合使您的 JSON 响应格式更加一致。以提高生产力和效率为目标,JSON API 因其可以消除多余服务器请求的高效缓存功能而受到吹捧。
在这篇文章中,我们将定义 JSON API 是什么,并了解如何使用它来构建高效的 API。我们将介绍 JSON API 的一些主要优点,并通过 FitBit 的案例研究了解该规范在实践中的应用情况。希望本概述将介绍 JSON API 的新手,并帮助您判断它是否适合您的 API 场景。
什么是 JSON API (JSONAPI.org)?
JSON API 是一种适用于 HTTP 的格式。它描述了客户端应如何从服务器请求或编辑数据,以及服务器应如何响应所述请求。该规范的一个主要目标(现在是稳定的 v1.0)是优化 HTTP 请求;在请求数量和客户端和服务器之间交换的数据包大小方面。
“JSON API 是一种有线(Wire)协议,用于通过 HTTP 增量获取和更新图形” ——耶胡达·卡茨
在 JSON API 中,客户端和服务器都在请求文档中发送 JSON API 数据,带有以下标头,而不指定媒体类型参数:
Content-Type: application/vnd.api+json
JSON API 表示如何调用资源以及如何共享相关链接。JSON 对象位于请求的根部,它必须包含资源数据、错误或元信息。数据以及与数据的关系可以通过 GET 调用来获取,如下所示:
GET /articles HTTP/1.1
Accept: application/vnd.api+json
以下是资源类型 `articles` 在 JSON API 响应中的显示方式:
// ...
{
"type": "articles",
"id": "1",
"attributes": {
"title": "Rails is Omakase"
},
"relationships": {
"author": {
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": { "type": "people", "id": "9" }
}
}
}
// ...
到目前为止,相当标准的东西。JSON API 支持创建、更新和删除资源的典型 CRUD 流程。JSON API 将始终向后兼容,它是一个社区驱动的计划,在 Github 上接受拉取请求。
使用 JSON API 的好处
既然我们对 JSON API 是什么有了基本的了解,那么有哪些独特的优势使它脱颖而出?
复合文档
复合文档是 JSON API 中的一项独特功能,允许服务器将相关资源与请求的主要资源一起发送——如果实施得当,这可以减少必要的 HTTP 请求的数量。复合文档使用 include 参数工作,如下所示:
GET https://api.example.com/posts?include=author
复制
这使您能够在初始请求中包含其他资源。
稀疏字段集
如果您使用复合文档来包含相关资源,您可能会遇到回复量大的问题。再一次,JSON API 有一个解决方案。
JSON API 的另一个独特方面是稀疏字段集,它使客户端只能从特定字段请求数据。它通过将要检索的字段添加到具有资源名称和所需字段的 URI 参数来工作。这提供了额外的定制,可以减少臃肿。它看起来像:
GET /articles?include=author&;fields[articles]=title,body&;fields[people]=name HTTP/1.1
Accept: application/vnd.api+json
复制
稀疏字段集是一种标准化方法,它允许客户端仅指定他们希望从对象中包含在响应中的属性。使用稀疏字段集,您只能获得所需的字段,提供独特的定制潜力,这对精益数据共享环境很有吸引力。
可选性
JSONAPI.org 中的许多功能都是可选的;您可以关闭或打开它们。这些功能使客户能够决定接受哪些资源,从而很好地适应精益的移动环境。让客户就如何检索和处理数据达成一致是有帮助的,因为它消除了冗余和优化以减少膨胀。
优化功能
JSON API 配备了许多功能来优化 API 返回包。JSON API 中的特殊服务器端操作包括排序和分页;将返回资源的数量限制为子集的能力,包括 first、last、next 和 prev 链接。
缓存
在他的演讲中,Lee 强调了定义良好的资源如何提高缓存能力,从而提高最终用户的“感知速度”。
“因为数据变化影响的资源更少,所以数据变化时失效的资源更少”
在 JSON API 用例中,缓存本质上是内置在 HTTP 中的。由于使用 JSON API 的客户端以相同的方式访问数据,因此他们不需要将数据存贮在不同的位置。这种设计可能需要转变思想,但如果使用得当,可以带来显着的优化优势。
JSON API 如何在实践中使用:FitBit 案例研究
让我们看看 JSON API 如何在实践中实现以设计高效的 API,使用 FitBit 作为现实生活中的案例研究。
Jeremiah Lee 在 FitBit 领导 API 开发 4 年,在此期间他参与了他们的 JSON API 采用。健身可穿戴公司 FitBit 拥有蓬勃发展的 API 程序;在每年 40 亿次请求中,有 1/4 是通过第三方应用程序完成的,收入可观。
符合 API 风格有助于标准化客户端
一个常见的问题是当不同的客户端类型偏好不同的方法来从服务器检索数据时。围绕功能区域形成的工程团队通常一次一个平台地逐步实施新功能,并在每个客户端中找到相反的约束。
Lee 描述了 FitBit 团队如何拥有四个主要客户:Android、iOS、Windows 和 Web。一个主要问题是 Android 和 iOS 对 API 应该如何运行有非常不同的想法。iOS 更喜欢较少的网络请求和较大的 API 响应,而 Android 更喜欢更多的网络请求和较小的 API 响应。
为了将这些约束规范化为一致的数据模型,团队必须首先解决请求数量和请求大小之间的争论。FitBit 团队在具有敌对数据网络的移动环境中工作,无法依赖理想的客户端连接。
相信 HTTP/2、TLS 1.3 和改进的 LTE 网络的日益普及,FitBit 团队决定他们可以减少请求的开销、发出并发请求并减少安全延迟问题,同时相信更多弹性连接。这将导致他们采用更小的资源和许多轻量级的 HTTP 请求。
JSON API 帮助创建一致的数据模型
“如果没有明确的指导,数据模型可能会变得混乱。” ——耶利米·李
Lee 描述了在 FitBit,他们的 API 如何开始类似于“视图模型”;现有端点变得超载,数据相关性松散,而不是范围广泛。团队正在根据用户体验视图重载端点。
随着客户体验随着时间的推移而发展,团队正在以任意方式拆分数据。由于没有权威或风格可以遵循,这造成了很多不一致。客户端和服务器数据模型之间的错位造成了问题。团队需要就如何检索数据和处理数据达成一致,并且需要能够以很少的开销检查数据更改。
他们倾向于使用 JSON API 来规范化他们的数据。使用 JSON API 定义数据之间关系的能力,他们能够建立客户端-服务器通信期望。
JSON API 有助于保持同步
FitBit 案例中的另一个问题是与服务器保持同步。他们的设备需要经常与服务器同步,并且这些数据也可以被第三方应用程序修改。
这些更改必须非常快速地反映在所有 API 客户端中。JSON API 利用的 HTTP 缓存使他们能够防止召回过时的数据,从而减少冗余并提高最终用户的感知速度。根据 Lee 的说法,这真的开始在一个应用程序中叠加多种体验。
比较 JSON API 和 GraphQL
既然我们本质上是在讨论使用图形,为什么不使用 GraphQL 呢?虽然您可以使用 GraphQL 实现许多相同的功能,但 Lee 看到了采用 JSON API 的两个主要好处:分页和可缓存性。
分页是 GraphQL 没有专门解决的一个领域。或者,当客户端请求它们时,JSON API 会向客户端提供诸如 next 和 prev 之类的链接。由于 GraphQL 中的分页完全由客户端处理,Lee 认为这很不幸,因为客户端可能会在不知不觉中进行昂贵、耗时的数据库查询。
GraphQL 也没有利用 HTTP 缓存功能,因为它与协议无关。由于没有建议的通用方法,这意味着每个 GraphQL API 处理缓存的方式都会略有不同。
“我个人认为缓存对于客户端性能考虑来说太重要了,不能事后考虑” ——耶利米·李
Lee 还指出,使用 JSON API 意味着开发人员不必采用像 GraphQL 这样的另一个工具链,而是可以继续使用他们很可能已经熟悉的技术。
GraphQL 的许多好处,例如查询效率和减少往返调用,都可以在 JSON API 中使用稀疏字段集和复合文档进行匹配。JSON API 因此可以提供与 GraphQL 相同的功能。
考虑将 JSON API 用于“实用”的 API 设计
JSON API LogoJeremiah Lee 称其为“务实”,我们必须同意。如上所述,让客户端和服务器共享一个通用数据模型(如 JSON API)有很多优点。
“JSONAPI.org 规范应该是您的智能默认设置” ——耶利米·李
虽然 JSON API 并不适合所有情况,但许多人声称它是客户端和服务器通过 HTTP 共享通用数据接口的一种很好的默认方式。凭借上面列出的优势,以及它的健康采用,JSON API 似乎是 API 风格的有力竞争者。
我们鼓励您自己阅读规范。您如何看待 JSONAPI.org?您使用什么规范来定义您的 API 和数据模型?