问题描述
目前,在 graphql-java 库.它确实具有一些基本的中继支持,在其中,我们可以创建connection
,这是Facebook推荐的实现分页的方法.
此是有助于实现该目标的方法.但是,由于没有文档,因此很难理解此功能的工作原理.如果某人已经有一个允许使用graphql-java库进行基本查询(例如Add
,delete
,fetch
等)的现有模型,那么有人可以细分他们添加分页支持的步骤吗?
Currently, I see no existing support for pagination in the graphql-java library. It does have some basic relay support, where-in, we can create a connection
, Facebook's recommended way of implementing pagination.
This is the method which helps achieve that. However, with no documentation I'm finding it hard to understand how this function works. Can someone break-down the steps they would take to add pagination support if they already have an existing model which allows basic queries like Add
, delete
, fetch
etc. using the graphql-java library?
推荐答案
您甚至不需要中继连接来支持分页.您的查询可以简单地接受页码和大小(或限制/偏移量)作为参数并返回列表-完成.但是,如果您想要中继连接,例如Book
类型,您将执行以下操作:
You don't even need Relay connections to support pagination. Your query could simply accept a page number and size (or limit/offset) as arguments and return a list - done.But, if you wanted Relay connection for e.g. Book
type, you'd do something like the following:
Relay relay = new Relay();
GraphQLOutputType book = ...; //build your normal Book object type
GraphQLObjectType bookEdge = relay.edgeType(book.getName(), book, null, Collections.emptyList());
GraphQLObjectType bookConnection = relay.connectionType(book.getName(), bookEdge, Collections.emptyList());
因此,您将拥有符合的BookConnection
类型.中继连接规范.
As a result, you'd have a BookConnection
type that conforms to the Relay connection spec.
对于具有基本GraphQL的示例,您有一个简单的Web应用程序此处.
As for the example with basic GraphQL, you have a simple web app here.
连接规范自然适合支持基于光标的分页的数据存储,但是在与不同的分页样式一起使用时需要一些创造力.
The connection spec naturally fits a data store that supports cursor based pagination, but needs some creativity when used with different pagination styles.
1)如果您希望使用基于简单偏移量的分页,则可以决定将after
视为偏移量(表示将传递数字),而将first
视为限制:
1) If you wish to use simple offset based paging, you can decide to treat after
as the offset (meaning a number would be passed), and first
as the limit:
SELECT * FROM ORDER BY timestamp OFFSET $after LIMIT $first
before
和last
相同,只是方向不同.
The same for before
and last
, just different direction.
2)另一种方法是将after
/before
视为排序列的最后一次看到的值(这样,将传递实际的(混淆的)值):
2) Another way is to treat after
/before
as the last seen value of the sort column (so an actual (obfuscated) value would be passed):
SELECT * FROM ORDER BY timestamp WHERE timestamp > $after LIMIT $first
我还建议您看一下我的项目 graphql-spqr ,使用示例应用程序,使开发GraphQL API变得非常简单.
I'd also recommend you take a look at my project, graphql-spqr, with an example app, that makes developing GraphQL APIs dead simple.
例如,您将创建如下的分页结果:
For example, you'd create a paginated result like this:
public class BookService {
@GraphQLQuery(name = "books")
//make sure the argument names and types match the Relay spec
public Page<Book> getBooks(@GraphQLArgument(name = "first") int first, @GraphQLArgument(name = "after") String after) {
//if you decide to fetch from a SQL DB, you need the limit and offset instead of a cursor
//so, you can treat "first" as count as "after" as offset
int offset = Integer.valueOf(after);
List<Book> books = getBooksFromDB(first, offset);
Page<Book> bookPage = PageFactory.createOffsetBasedPage(books, totalBookCount, offset);
return bookPage;
}
}
还有许多其他方法可以创建Page
实例,这只是最简单的方法.
There's many other ways to create a Page
instance, this is just the most straight-forward one.
然后您将根据Java类生成模式:
You'd then generate a schema from your Java class:
GraphQLSchema schema = new GraphQLSchemaGenerator()
.withOperationsFromSingleton(new BookService())
.generate();
GraphQL graphQL = GraphQLRuntime.newGraphQL(schema).build();
并执行查询:
ExecutionResult result = graphQL.execute("{books(first:10, after:\"20\") {" +
" pageInfo {" +
" hasNextPage" +
" }," +
" edges {" +
" cursor, node {" +
" title" +
"}}}}");
但是,再次,如果您不使用Relay,那么确实不需要使事情复杂化.如果您的存储设备自然支持基于光标的分页,请继续使用它.如果不是,则只需使用简单的limit/offset参数并返回一个列表,然后忘记连接规范.创建它是为了使Relay能够在各种情况下自动管理分页,因此,如果您不使用Relay和/或具有基于光标的分页的DB,那么它几乎总是完全过失.
But, again, if you are not using Relay there's really no need to overcomplicate things. If your storage supports cursor-based pagination naturally, go for it. If it doesn't, just use the simple limit/offset arguments and return a list, and forget the connection spec. It was created to enable Relay to automatically manage paging in various scenarios, so it's almost always a total overkill if you're not using Relay and/or a DB with cursor-based pagination.
这篇关于GraphQL:如何使用graphQL-java实现分页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!