GraphQL: один большой запрос против множества маленьких запросов

#node.js #graphql #apollo #apollo-client #apollo-server

#node.js #graphql #apollo #apollo-клиент #apollo-сервер

Вопрос:

Я знаю, что этот вопрос стар как мир — и это не серебряная пуля. Но я думаю, что там может быть четкая схема, и я бы не хотел изобретать колесо.

Рассмотрим следующие два варианта схемы:

Подход 1) Моя оригинальная реализация

 type Query {
  note(id: ID!): Note
  notes(input: NotesQueryInput): [Note!]!
}
  

Подход 2) Мой текущий экспериментальный подход

 type DatedId {
  date: DateTime!
  id: ID!
}

type Query {
  note(id: ID!): Note
  notes(input: NotesQueryInput): [DatedId!]!
}
  

Различия заключаются в:

при подходе 1) запрос notes либо вернет список потенциально больших объектов Note

при подходе 2) запрос notes вернет гораздо меньшую полезную нагрузку, но затем потребуется выполнить n дополнительных запросов

Так что мой вопрос с Аполлона клиент / сервер стека в памяти-кэш, который является лучшим подходом.для создания отзывчивого клиента с масштабируемым сервером.


Примечания

  • При подходе 1 — у моего 500mb dyno (сервера heroku) закончилась память.

  • Я ожидаю, что при любом подходе я буду реализовывать разбивку на страницы с помощью шаблона соединения / ребра

  • сервер graphql предназначен в первую очередь для обслуживания моего собственного интерфейса.

Комментарии:

1. Из вашего вопроса немного неясно… предполагается ли здесь, что при вашем втором подходе вы делаете один запрос, запрашиваете notes , а затем впоследствии один запрос на возвращаемый идентификатор, на этот раз запрашивая note поле?

2. Кроме того, запрос «наилучшего подхода» делает этот вопрос широким и зависит от мнения. Было бы полезно предоставить некоторые критерии. Есть ли что-нибудь, кроме нехватки памяти на вашем сервере, к чему вы пытаетесь обратиться. Вместо того, чтобы спрашивать «каков наилучший подход», можем ли мы вместо этого спросить, какой подход поможет мне достичь x, y и z?

3. @DanielRearden — да, подход 2 требует впоследствии одного запроса на возвращаемый идентификатор. и я попытался отредактировать вопрос, чтобы добавить к нему больше параметров

Ответ №1:

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

Единственный другой способ обойти эту конкретную проблему — разбить ваш запрос на несколько запросов меньшего размера. Однако предлагаемый вами подход страдает от нескольких проблем:

  • В конечном итоге вы будете забивать свой сервер и базу данных значительно большим количеством запросов
  • Загрузка вашего пользовательского интерфейса может занять больше времени, в зависимости от того, нужно ли немедленно отображать запрошенные данные
  • Обработка сценария, когда один из ваших запросов завершается с ошибкой, или попытка повторить неудачный запрос, может оказаться сложной задачей

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

Еще один вариант, который вы можете рассмотреть, — это использование отложенных запросов. Эта экспериментальная функция была добавлена специально с учетом дорогостоящих запросов. Создав одно или несколько полей вашего Note типа deferred, вы бы эффективно возвращали null для них изначально, и их значения были бы отправлены во втором ответе «patch» после их окончательного разрешения. Это отлично работает для полей, разрешение которых дорого, но также может помочь с полями, которые возвращают большой объем данных.