10月8日至10日与我们在纽约市相聚,了解关于 GraphQL 联邦和 API 平台工程的最新技巧、趋势和新闻。加入我们于2024年在纽约举办的 GraphQL 大会
文档
免费开始

分页


Apollo分页提供了方便便捷的方式与观察分页API进行交互。它提供了一种灵活强大的方式来处理分页数据,并且可以与以下进行交互: 和偏移量分页。它的主要特点包括:

  • 观察分页数据
  • 前进、后退和双向分页支持
  • 分页支持
  • 支持自定义模型类型

Apollo分页提供了两个类以与分页端点进行交互GraphQLQueryPagerAsyncGraphQLQueryPager。它们的API非常相似,但后者支持 async / await,以便在异步上下文中使用。

Apollo分页是其自己的Swift Package,为了使用分页功能,您需要将apollo-ios-pagination SPM包添加到您的项目中,以及apollo-ios

使用 GraphQLQueryPager

GraphQLQueryPager 是一个简单、灵活且强大的方式来与分页数据交互。虽然它有一个标准的初始化器,但建议使用便利的初始化器,这可以简化创建 GraphQLQueryPager 实例的过程。

在此示例中,初始化了一个 GraphQLQueryPager,它以光标分页的方式进行正向查询分页:

let initialQuery = MyQuery(first: 10, after: nil)
let pager = GraphQLQueryPager(
client: client,
initialQuery: initialQuery,
extractPageInfo: { data in
CursorBasedPagination.Forward(
hasNext: data.values.pageInfo.hasNextPage ?? false,
endCursor: data.values.pageInfo.endCursor
)
},
pageResolver: { page, paginationDirection in
// As we only want to support forward pagination, we can return `nil` for reverse pagination
switch paginationDirection {
case .next:
return MyQuery(first: 10, after: page.endCursor ?? .none)
case .previous:
return nil
}
}
)

在此示例中,GraphQLQueryPager实例通过一个extractPageInfo闭包初始化,该闭包从查询结果中提取分页信息,并一个pageResolver闭包,它提供要执行的下一次分页查询。随后,GraphQLQueryPager实例可用来获取分页数据,并观察分页数据的变更。

每当翻页器需要加载新页面时,它将调用extractPageInfo闭包,传入最后一次查询的结果数据。您的extractPageInfo实现应该返回一个PaginationInfo值,可用于查询下一页。然后翻页器调用pageResolver,传递由extractPageInfo闭包提供的PaginationInfo。您的pageResolver实现应该返回一个使用给定PaginationInfo查询下一页的查询。

我们可以同样通过向extractPageInfo闭包提供OffsetPagination.Forward而不是CursorBasedPagination.Forward来支持基于向前偏移的分页。

使用AsyncGraphQLQueryPager

AsyncGraphQLQueryPagerGraphQLQueryPager类类似,但它支持async/await,以在异步上下文中使用。

在此示例中,初始化了一个AsyncGraphQLQueryPager,它以基于游标的分页方式在正向方向上分页单个查询

let initialQuery = MyQuery(first: 10, after: nil)
let pager = AsyncGraphQLQueryPager(
client: client,
initialQuery: initialQuery,
extractPageInfo: { data in
CursorBasedPagination.Forward(
hasNext: data.values.pageInfo.hasNextPage ?? false,
endCursor: data.values.pageInfo.endCursor
)
},
pageResolver: { page, paginationDirection in
// As we only want to support forward pagination, we can return `nil` for reverse pagination
switch paginationDirection {
case .next:
return MyQuery(first: 10, after: page.endCursor ?? .none)
case .previous:
return nil
}
}
)

注意,其初始化方法与GraphQLQueryPager相同,使用相同的参数。

订阅结果

GraphQLQueryPagerAsyncGraphQLQueryPager可以获取数据,但调用者必须订阅结果才能接收数据。subscribe方法提供了一个闭包,每当翻页器获取新页面数据时都会调用该闭包。subscribe方法是一个方便的方法,它确保闭包在主线程上调用。

// Guaranteed to run on the main thread
pager.subscribe { result in
switch result {
case .success(let data):
// Handle the data
case .failure(let error):
// Handle the error
}
}

GraphQLQueryPagerAsyncGraphQLQueryPager 都是 Combine Publisher。因此,所有 Publisher 方法都可用,例如 sink、assign、map、filter 等。

// Can run on any thread
pager.sink { result in
switch result {
case .success(let data):
// Handle the data
case .failure(let error):
// Handle the error
}
}

数据获取

GraphQLQueryPager 类提供了几个方法来获取分页数据: fetchrefetchloadNextloadPreviousloadAll

  • fetch:获取第一页数据。必须在调用 loadNextloadPrevious 之前调用。提供了一个完成处理程序,允许调用者在被通知数据检索操作完成时进行操作。
  • refetch:取消所有正在进行的获取 操作 和 重置分页器到其初始状态。获取第一页数据。提供了一个完成处理程序,允许调用者被通知数据检索操作何时完成。
  • loadNext:获取下一页数据。只能在调用 fetch 后调用。提供了一个完成处理程序,允许调用者在操作完成后被通知,附带一个可选的 Error? 参数,其中包含可能发生的任何使用错误。
  • loadPrevious:获取上一页数据。只能在调用 fetch 后调用。提供了一个完成处理程序,允许调用者在操作完成后被通知,附带一个可选的 Error? 参数,其中包含可能发生的任何使用错误。
  • loadAll:获取所有页面的数据。如果没有检测到初始页面,它将首先调用 fetch 来获取第一页数据。将继续获取所有页面,直到一个 PageInfo 对象指示没有更多页面要获取。此函数与前向、反向和双向分页兼容。提供了一个完成处理程序,允许调用者在操作完成后被通知,附带一个可选的 Error? 参数,其中包含可能发生的任何使用错误。

AsyncGraphQLQueryPager 类提供了与异步函数相同的方法,但不需要完成处理程序,因为在异步情况下不需要。

取消正在进行的请求

GraphQLQueryPager 类提供了一个 reset 方法,可用于取消所有正在进行的获取 操作 并停止监视缓存数据的更改。这不会取消任何分页器的订阅者。一旦分页器状态已重置,您可以调用 fetch 重新开始接收更新,并且现有订阅者将继续接收更新。

错误处理

GraphQLQueryPager类可以抛出两种类型的错误:由网络操作引起的错误或由使用引起的错误。当分页器遇到网络错误,如超时或连接错误时,将通过网络操作结果的Result传递给订阅者来暴露给用户。使用错误,例如取消或在一个加载正在进行时尝试开始一个新的获取,会被抛出为PaginationError类型(对于AsyncGraphQLQueryPager),或者在每种获取方法的回调中暴露(对于GraphQLQueryPager)。请注意,GraphQLQueryPager的回调是可选的,用户可以选择忽略它们。

GraphQLQueryPager中的使用错误

方法loadNextloadPreviousloadAll都有一个完成处理函数,它和一个Result类型一起被调用。这个Result类型可能包含分页数据或一个PaginationError类型。常见的分页错误是在已有正在进行的加载时尝试获取数据,或在调用fetch前尝试获取前一个或后一个页面。

// Attempting to fetch a previous page without first calling `fetch`
pager.loadNext { error in
if let error {
// Handle error
} else {
// We have no error, and are finished with our fetch operation
}
}
// Note that we can silently ignore the error
pager.loadNext()

AsyncGraphQLQueryPager中的使用错误

AsyncGraphQLQueryPager可以直接抛出PaginationError类型,而不是通过完成处理函数来暴露它。作为一个本征异步类型,AsyncGraphQLQueryPager可以在Task内部抛出错误并将其转发给调用者。

// Attempting to fetch a previous page without first calling `fetch`
try await pager.loadNext()
// Similarly, we can silently ignore the error
try? await pager.loadNext()
上一页
创建客户端
下一页
使用自定义响应模型
评分文章评分在GitHub上编辑Edit论坛Discord

©2024阿波罗图形公司,业务名为阿波罗GraphQL。

隐私政策

公司