当前位置: 首页 > news >正文

AIP-158 分页

编号158
原文链接AIP-158: Pagination
状态批准
创建日期2019-02-18
更新日期2019-02-18

API通常需要提供数据集,最常见的是 List 标准方法。但集合大小往往是不受控制的,会随着时间增长,提高了查找时间和通过网络传输的应答大小。因此对集合进行分页是非常重要的。

指南

返回数据集的接口 必须 一开始就提供分页功能,因为向现存方法添加分页功能是无法向后兼容的变更。

// The request structure for listing books.
message ListBooksRequest {
  // The parent, which owns this collection of books.
  // Format: publishers/{publisher}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "library.googleapis.com/Book"
    }];

  // The maximum number of books to return. The service may return fewer than
  // this value.
  // If unspecified, at most 50 books will be returned.
  // The maximum value is 1000; values above 1000 will be coerced to 1000.
  int32 page_size = 2;

  // A page token, received from a previous `ListBooks` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListBooks` must match
  // the call that provided the page token.
  string page_token = 3;
}

// The response structure from listing books.
message ListBooksResponse {
  // The books from the specified publisher.
  repeated Book books = 1;

  // A token that can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}
  • 返回集合的请求消息 应当 定义 int32 page_size 域,允许用户设定返回的最大结果数量。
    • page_size 域 不得 是必需域。
    • 如果用户未设定 page_size (或设定为 0 ),API选择合适的默认值。API 应当 在文档中记录默认值。API 不得 返回错误。
    • 如果用户设定的 page_size 大于 API 允许的最大值,API 应当 将其强制设置为允许的最大页大小。
    • 如果用户为 page_size 设定了负值,API 必须 返回 INVALID_ARGUMENT 错误。
    • API 可以 返回少于请求数量(包括零)的结果,即使未到达集合末尾。
  • 集合的请求消息 应当 定义 string page_token 域,允许用户前进到集合的下一页。
    • page_token 域 不得 是必需域。
    • 如果用户在后续分页请求中修改了 page_size ,服务 必须 遵守新的页大小。
    • 用户要保持接口的所有其他参数不变;如果任何参数不同,API 应当 返回 INVALID_ARGUMENT 错误。
  • 应答 不得 是流式应答。
  • 返回集合的应答消息 应当 定义 string next_page_token 域,为用户提供用于检索下一页的页令牌。
    • 包含分页结果的域 应当 是消息的第一个域,编号为 1 。它 应当 是重复域,包含一组资源,构成一个结果页。
    • 如果已到达集合末尾, next_page_token 域 必须 为空。这是告诉用户“集合结束”的 唯一 方法。
    • 如果未到达集合末尾(或API无法及时确认),API 必须 提供 next_page_token 。
  • 返回集合的应答消息 可以 提供 int32 total_size 域,为用户提供列表总项目数。
    • 总数 可以 是估计值(此时API 应当 在文档中明确记录)。

跳过部分结果

分页操作请求 可以 定义一个 int32 skip 域,允许用户跳过部分结果。

skip 值 必须 表示要待跳过的单个资源数量,而非页数量。

例如:

  • 没有页令牌,且 skip 值为 30 的请求,返回从第 31 个结果开始的单个页。
  • 带有对应第51个结果的页令牌(因为前50个结果已在第1页返回),且 skip 值为 30 的请求,返回从第 81 个结果开始的单个页。

如果提供的 skip 值使得游标移动到结果集末尾之后,应答 必须 是 200 OK ,且结果集为空,不再提供 next_page_token 。

不透明

API 提供的页令牌 必须 是不透明(符合URL要求)的字符串, 不得 让用户能够解析。如果用户能解析令牌, 他们真的会这么做 。这实际上让 API 分页的实现细节成为 API 界面的一部分,并且无法在不影响用户的情况下修改实现细节。

警告 对透明的页令牌进行 Base-64 编码 不是 有效的混淆机制。

如果页令牌不需要存储在数据库中,也不包含敏感数据,API 可以 定义一个包含所需数据的内部protocol buffer消息,发送消息的序列化结果(base-64 编码)作为混淆页令牌。

页令牌 必须 只用于提供分页过程继续位置的指示。 不得 提供对底层资源的任何形式的授权,授权 必须 像任何其他请求一样执行,无论是否存在页令牌。

页令牌失效

许多 API 在内部将页令牌存储在数据库中。此时API 可以 在发送页令牌后,经过一段合理时间,使页令牌失效,避免额外存储大量几乎无效的数据。这种行为不需要记录到文档中。

注意 不同API的合理时间可能不同,一个好的经验法则是3天。

向后兼容

向现存接口添加分页特性是无法向后兼容的变更。乍看很奇怪;向 proto 消息添加域通常是向后兼容的。然而添加分页在 行为上 是不兼容的。

考虑一个用户,集合中有 75 个资源。他已经编写并部署了代码。如果 API 后续添加分页域,将默认值设置为 50,他的代码将失效:代码原本取得所有资源,现在只取得前 50 个(并且代码还不知道如何进行分页)。即使 API 设置了很高的默认限制,例如 100,用户的集合可能会增长, 最后 代码还会失效。

此外,客户端库实现了自动分页,通常使用不同的方法签名区分分页接口和非分页接口。这意味着向未分页方法添加分页,将导致这些库产生破坏性更改。

因此,始终在返回集合的接口中 预先 添加分页很重要。真的很重要。以后再添加分页,无法避免不给现有用户带来麻烦。

警告 这也意味着,除了展示分页域外,接口的 实际实现 必须 使用有限的默认值。对于最初较小的集合,实现一个内存版本(取得的所有内容之后再分页)是合适的。

修订记录

  • 2020-05-24 明确指出添加分页会破坏客户端库。
  • 2020-05-13 添加跳过部分结果指导原则。
  • 2020-08-24 明确指出应答不是流式应答。
  • 2020-06-24 明确指出页大小对用户始终是可选的。
  • 2019-02-12 添加关于分页域的指导原则。
  • 2019-08-01 将示例从 “shelves” 改为 “publishers”,提供更好的资源所有权示例。
  • 2019-07-19 将不透明性要求从“应该”改为“必须”。

相关文章:

  • Leetcode 215 数组中的第K个最大元素
  • 一、计算机等级考试——标准评分
  • Leetcode 37: 解数独
  • 【数据分析】复杂实验,通过正交表组合来进行实验设计
  • 安全渗透测试的全面解析与实践
  • 虚拟机ip配置
  • 网页制作11-html,css,javascript初认识のCCS样式列表(上)
  • 【Azure 架构师学习笔记】- Azure Databricks (14) -- 搭建Medallion Architecture part 2
  • Vue 3 中 unref 的作用与 Vue Router currentRoute 的知识
  • Spring Boot整合RabbitMQ
  • 蓝桥杯 - 每日打卡(类斐波那契循环数)
  • 17028djwcb
  • 探秘基带算法:从原理到5G时代的通信变革【六】CRC 校验
  • Spark(6)vm与centos虚拟机
  • DeepSeek API使用及私有化部署
  • 【向量数据库Weaviate】与ChromaDB的差异、优劣
  • week 2 - Branching - Arrays
  • JVM内存管理
  • 线程池的工作流程
  • VMware如何配置IP网络
  • “彩虹滑道”项目两男童相撞飞跌出去,景区:工作人员误判导致
  • 履新宿州市政府党组书记后,任东暗访五一假期安全生产工作
  • 沈晓萍︱严金清:比斯坦因更早获得敦煌文物的无锡名士
  • 空调+零食助顶级赛马备战,上海环球马术冠军赛即将焕新登场
  • 美乌矿产协议预计最早于今日签署
  • 国台办:“台独”是绝路,外人靠不住