Nano Hash - криптовалюты, майнинг, программирование

GraphQL: как реализовать разбиение на страницы с помощью graphQL-java?

В настоящее время я не вижу существующей поддержки разбивки на страницы в библиотеке graphql-java . У него есть некоторая базовая поддержка ретрансляции, в которой мы можем создать connection, рекомендованный Facebook способ реализации разбивки на страницы.
Это метод, который помогает добиться этого. Однако без документации мне трудно понять, как работает эта функция. Может ли кто-нибудь разбить шаги, которые они предприняли бы для добавления поддержки разбивки на страницы, если у них уже есть существующая модель, которая позволяет выполнять базовые запросы, такие как 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) Другой способ - рассматривать _9 _ / _ 10_ как последнее увиденное значение столбца сортировки (поэтому будет передано фактическое (скрытое) значение):

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, нет необходимости усложнять вещи. Если ваше хранилище естественно поддерживает разбиение на страницы на основе курсора, сделайте это. Если это не так, просто используйте простые аргументы ограничения / смещения и верните список и забудьте о спецификации подключения. Он был создан, чтобы позволить Relay автоматически управлять разбивкой по страницам в различных сценариях, поэтому это почти всегда полный перебор, если вы не используете Relay и / или БД с разбивкой на страницы на основе курсора.

16.06.2017
  • Замечательный ответ! 16.06.2017
  • @ user3728233 Рад помочь :) 16.06.2017
  • Для большинства сценариев разбивки на страницы вам все равно нужно знать общее количество. Как бы вы справились с этим, просто добавив переменные пропуска / ограничения? 09.01.2019
  • На странице @Donuts Relay уже указано общее количество (на данный момент отсутствует в SPQR, но будет добавлено в ближайшее время, также легко добавляется вручную). В противном случае вы можете вернуть тип объекта, инкапсулирующий список результатов и счетчик. 10.01.2019
  • @kaqqao Я имел в виду вариант, в котором реле не используется. Итак, да, я вижу 2 варианта: 1, ваш запрос возвращает тип, который имеет как массив результатов, так и сумму. или 2, в вашей схеме graphql ваш тип запроса может содержать дополнительное сопоставление для запроса count - так что у вас могут быть книги, а затем booksCount (который возвращает int). Недостатком варианта 1 является то, что для каждого типа, который может быть разбит на страницы, у вас должен быть дополнительный тип для обработки разбиения на страницы, потому что graphql не обрабатывает универсальные шаблоны. как будто у меня не может быть PagedResult ‹Book› в моей бэкэнд-карте с типом PagedResult в graphql 11.01.2019
  • @Donuts Если вы делаете это вручную, это немного неудобно, поэтому может быть проще просто придерживаться спецификации подключения, поскольку помощники уже существуют, чтобы упростить создание типов подключения. Если вы используете SPQR, вы, безусловно, можете настроить его для генерации определенного типа GraphQL из универсального Java-приложения «на лету» (так работает Page<Book>). 11.01.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..