主页 > 手机  > 

AIP-158分页

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 /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 将不透明性要求从“应该”改为“必须”。
标签:

AIP-158分页由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“AIP-158分页