Size: a a a

GraphQL — русскоговорящее сообщество

2020 October 02

ОЛ

Олег Линьков... in GraphQL — русскоговорящее сообщество
То что вы передаете аргумент, совсем не аргумент)
источник

AM

Alexey Mikhaylov in GraphQL — русскоговорящее сообщество
Kirill Kaiumov
Ваш первый вариант правильный и с точки зрения graphql всё верно. Если ошибка, значит где-то ошиблись в реализации. Я сам сделал недавно точно такую же query:
query {
 inbox {
   notifications {
     ... on NotificationConnection {
       nodes {
         id
       }
     }
     
     ... on NotAuthenticatedProblem {
       message
     }
   }
 }
}
спасибо, пойду давить бекендеров)
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
>> То что вы передаете аргумент, совсем не аргумент)

Возможно я как то запутано написал, попробую подробнее.

Запрос:

{
   users(first: 10) {
       id
       name
       allBooks {
           id
           name
       }
   }
}


Здесь нет никаких проблем, можно использовать даталоадер в резолвере allBooks, batch функция будет принимать на вход список идентификаторов пользователей и делать запрос в сервис книг, при помощи метода getAllBooksByUserIds(userIds). Т.е. по списку пользователей получаем список книг одним запросом.

Но как быть когда запрос нужно делать такой:
{
   users(first: 10) {
       id
       name
       books(first: 5) {
           id
           name
       }
   }
}



На каждое кол-во книг по даталоадеру не создашь, составной ключ конечно можно использовать, но не думаю что это удобно.
источник

KK

Kirill Kaiumov in GraphQL — русскоговорящее сообщество
Ilya Klimov
>> То что вы передаете аргумент, совсем не аргумент)

Возможно я как то запутано написал, попробую подробнее.

Запрос:

{
   users(first: 10) {
       id
       name
       allBooks {
           id
           name
       }
   }
}


Здесь нет никаких проблем, можно использовать даталоадер в резолвере allBooks, batch функция будет принимать на вход список идентификаторов пользователей и делать запрос в сервис книг, при помощи метода getAllBooksByUserIds(userIds). Т.е. по списку пользователей получаем список книг одним запросом.

Но как быть когда запрос нужно делать такой:
{
   users(first: 10) {
       id
       name
       books(first: 5) {
           id
           name
       }
   }
}



На каждое кол-во книг по даталоадеру не создашь, составной ключ конечно можно использовать, но не думаю что это удобно.
> batch функция будет принимать на вход список идентификаторов пользователей
да, а в эту же функцию есть возможность передавать значение аргумента first? В вашем примере это 5
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
Тогда для каждого значения first нужно будет создавать по даталоадеру.
источник

ОЛ

Олег Линьков... in GraphQL — русскоговорящее сообщество
два даталоадера один по юзерам, другой по книгам и все. Суть же проста, он из одиночных запросов делает IN и он не завязан на вашем контексте
источник

KK

Kirill Kaiumov in GraphQL — русскоговорящее сообщество
Ilya Klimov
Тогда для каждого значения first нужно будет создавать по даталоадеру.
не знаю, как у вас это реализовано, но у меня даталоадер – это руби класс, куда этот first аргумент можно передать. Мне не нужно создавать новые даталоадеры, я практически уверен, что у вас тоже можно так сделать.
Дальше остаётся задача, как эффективно достатать первые N книг для каждого юзера из БД, но это другой разговор 🙂
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
>> он из одиночных запросов делает IN

Для получения всех книг пользователя да, будет обычный select id, name from books where user_id IN (1, 2, 3), но задача получить N последних книг для каждого пользователя.

>> не знаю, как у вас это реализовано, но у меня даталоадер – это руби класс, куда этот first аргумент можно передать. Мне не нужно создавать новые даталоадеры, я практически уверен, что у вас тоже можно так сделать.

Получается что при каждом запросе у вас свой экземляр класса даталоадера?
источник

DT

Dmitry Tsepelev in GraphQL — русскоговорящее сообщество
Ilya Klimov
>> То что вы передаете аргумент, совсем не аргумент)

Возможно я как то запутано написал, попробую подробнее.

Запрос:

{
   users(first: 10) {
       id
       name
       allBooks {
           id
           name
       }
   }
}


Здесь нет никаких проблем, можно использовать даталоадер в резолвере allBooks, batch функция будет принимать на вход список идентификаторов пользователей и делать запрос в сервис книг, при помощи метода getAllBooksByUserIds(userIds). Т.е. по списку пользователей получаем список книг одним запросом.

Но как быть когда запрос нужно делать такой:
{
   users(first: 10) {
       id
       name
       books(first: 5) {
           id
           name
       }
   }
}



На каждое кол-во книг по даталоадеру не создашь, составной ключ конечно можно использовать, но не думаю что это удобно.
Кажется, что даталоадер тут не поможет, все равно придется сделать N запросов. В целом я бы очень не советовал делать вложенный paging
источник

KK

Kirill Kaiumov in GraphQL — русскоговорящее сообщество
Ilya Klimov
>> он из одиночных запросов делает IN

Для получения всех книг пользователя да, будет обычный select id, name from books where user_id IN (1, 2, 3), но задача получить N последних книг для каждого пользователя.

>> не знаю, как у вас это реализовано, но у меня даталоадер – это руби класс, куда этот first аргумент можно передать. Мне не нужно создавать новые даталоадеры, я практически уверен, что у вас тоже можно так сделать.

Получается что при каждом запросе у вас свой экземляр класса даталоадера?
> Получается что при каждом запросе у вас свой экземляр класса даталоадера?
всё так
источник

DT

Dmitry Tsepelev in GraphQL — русскоговорящее сообщество
Или paging не нужен, только первые 5 книг для каждого?
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
> всё так

Тогда это тот самый вариант с даталоадером для каждого first 🙂
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
> Или paging не нужен, только первые 5 книг для каждого?
Нет, только первые N + сортировка
источник

KK

Kirill Kaiumov in GraphQL — русскоговорящее сообщество
Ilya Klimov
> всё так

Тогда это тот самый вариант с даталоадером для каждого first 🙂
а можете показать свой dataloader?
источник

DT

Dmitry Tsepelev in GraphQL — русскоговорящее сообщество
а может сделать одним запросом без dataloader тогда? не знаю что за база, но такие штуки делаются через window function
источник

DT

Dmitry Tsepelev in GraphQL — русскоговорящее сообщество
источник

ОЛ

Олег Линьков... in GraphQL — русскоговорящее сообщество
Ilya Klimov
>> он из одиночных запросов делает IN

Для получения всех книг пользователя да, будет обычный select id, name from books where user_id IN (1, 2, 3), но задача получить N последних книг для каждого пользователя.

>> не знаю, как у вас это реализовано, но у меня даталоадер – это руби класс, куда этот first аргумент можно передать. Мне не нужно создавать новые даталоадеры, я практически уверен, что у вас тоже можно так сделать.

Получается что при каждом запросе у вас свой экземляр класса даталоадера?
почему in строится на основании user id? он строится на основе id книги например. Почитайте документацию
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
Dmitry Tsepelev
а может сделать одним запросом без dataloader тогда? не знаю что за база, но такие штуки делаются через window function
С SQL проблем нет, вариантов сделать last N for each group много. Мне больше интересно как это сделать без N+1 в GraphQL 🙂
источник

ОЛ

Олег Линьков... in GraphQL — русскоговорящее сообщество
даталоадер не несет в себе логику никогда, это максимально простая по логике фабрика запросов, поэтому провайдить нужно ей только конечные нужные id, ничего не мешает подготовить запрос для key
источник

I

Ilya Klimov in GraphQL — русскоговорящее сообщество
Kirill Kaiumov
а можете показать свой dataloader?
Сейчас сделано пока с проблемой N+1, трижды 🙂 Вот только начал рефакторинг, решения конечно есть, но решил сначала у комьюнити спросить, что бы вылосипеды не городить.
источник