加入我们,从10月8日至10日,在纽约市学习关于GraphQL联盟和API平台工程的最新的技巧、趋势和新闻。加入2024年纽约市的GraphQL峰会
文档
免费开始

使用自定义响应模型


GraphQLQueryPager不仅支持返回查询的类型,还支持自定义响应类型。自定义响应类型可以是集合或单个对象。这非常有用,当你想要将原始响应转换为用于应用程序消耗的自定义模型时。

转换现有响应类型

GraphQLQueryPager遵循Publisher协议,并提供一个map方法,允许您将原始响应转换为自定义响应类型。当以这种方式使用时,GraphQLQueryPager将处理生成Data类型,但允许每个Data类型转换为自定义响应类型。这在您想要在多个地方重用单个分页器并向视图模型转换原始数据时特别有用。

在这个例子中,我们取一个返回Result<PaginationOutput<MyQuery.Data, MyQuery.Data>>GraphQLQueryPager,并将原始响应转换为自定义响应类型Result<[Person], Error>

// This `GraphQLQueryPager` will return a `Result` of `PaginationOutput<MyQuery.Data, MyQuery.Data>`
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
switch paginationDirection {
case .next:
return MyQuery(first: 10, after: page.endCursor ?? .none)
case .previous:
return nil
}
}
)
// Elsewhere in the application
let cancellable = pager.map { result in
switch result {
case .success((let paginationOutput, let source)):
// We may or may not care about the source, but we can use it to transform the response or pass it through as needed.
// In this example, we ignore the source and transform the response into a custom response type.
let pages = paginationOutput.previousPages + [paginationOutput.initialPage] + paginationOutput.nextPages
let people = pages.flatMap { page in
data.values.nodes.map { Person(id: $0.id, name: $0.name) }
}
return Result<[Person], Error>.success(people)
case .failure(let error):
return .failure(error)
}
}.sink { result in
// NOTE: This is not guaranteed to run on the main thread. Dispatch to the main thread if necessary.
switch result {
case .success(let people):
// Handle the people
case .failure(let error):
// Handle the error
}
}

创建返回自定义响应类型的 GraphQLQueryPager

GraphQLQueryPager类还可以根据自定义类型进行初始化。当以这种方式使用时,GraphQLQueryPager将在自定义响应类型上操作,而不是在原始Data类型上。当您想要创建一个返回自定义响应类型的分页器,且不想将原始响应转换成自定义响应类型时,这很有用。

我们为此提供了转换集合类型的一种便捷方法。

在此示例中,我们创建了一个GraphQLQueryPager,将原始响应转换成自定义响应类型Result<([Person], UpdateSource), Error>。在此,我们将为每个分页查询的数据调用transform闭包,并将结果数组连接在一起。

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
}
},
transform: { data in
data.values.nodes.compactMap { node in
Person(id: node.id, name: node.name)
}
}
)

或者,您也可以返回一个单个模型类型,例如Result<(MyResponseModel, UpdateSource), Error>。为此,我们使用一个有三个参数的transform闭包,分别为previousPages, initialPage, nextPages

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
}
},
transform: { previousPages, initialPage, nextPages in
let allPages = previousPages + [initialPage] + nextPages
let people = allPages.flatMap { page in
data.values.nodes.map { Person(id: $0.id, name: $0.name) }
}
return MyResponseModel(people: people)
}
)
上一页
简介
下一页
方向性分页
评价文章评价在GitHub上编辑编辑论坛Discord

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

隐私政策

公司