GraphQL: как реализовать разбиение на страницы с GraphQL-Java?

В настоящее время я не вижу поддержки пагинации в библиотеке graphql-java. Он имеет некоторую базовую поддержку ретрансляции, где мы можем создать connectionFacebook рекомендовал способ реализации нумерации страниц.
Это метод, который помогает достичь этого. Однако без документации мне трудно понять, как работает эта функция. Может ли кто-то разбить шаги, которые они предпримут, чтобы добавить поддержку нумерации страниц, если у них уже есть существующая модель, которая допускает базовые запросы, такие как Add, delete, fetch и т.д., используя библиотеку graphql-java?

1 ответ

Решение

Вам даже не нужны релейные соединения для поддержки нумерации страниц. Ваш запрос может просто принять номер страницы и размер (или ограничение / смещение) в качестве аргументов и вернуть список - готово. Но, если вы хотите, чтобы релейное соединение, например, Book типа, вы бы сделали что-то вроде следующего:

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 тип, соответствующий спецификации соединения реле.

Что касается примера с базовым GraphQL, у вас есть простое веб-приложение здесь.

Спецификация соединения естественно подходит для хранилища данных, которое поддерживает нумерацию на основе курсора, но требует некоторой креативности при использовании с разными стилями нумерации страниц.

1) Если вы хотите использовать простую пейджинг на основе смещения, вы можете after в качестве смещения (что означает, что число будет передано), и first как предел:

SELECT * FROM ORDER BY timestamp OFFSET $after LIMIT $first

То же самое для before а также lastПросто другое направление.

2) Другой способ лечения after/before как последнее увиденное значение столбца сортировки (поэтому будет передано фактическое (запутанное) значение):

SELECT * FROM ORDER BY timestamp WHERE timestamp > $after LIMIT $first

Я также рекомендую вам взглянуть на мой проект graphql-spqr с примером приложения, которое упрощает разработку API-интерфейсов GraphQL.

Например, вы бы создали результат с разбивкой по страницам, например так:

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 Например, это самый простой.

Затем вы сгенерируете схему из вашего Java-класса:

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 с пагинацией на основе курсора.

Другие вопросы по тегам