Могу ли я использовать загрузчик данных без дозирования - PullRequest
0 голосов
/ 04 апреля 2020

Что меня действительно интересует в загрузчике данных, так это кэширование каждого запроса. Например, скажем, что мой запрос к graphql должен вызывать getUser ("id1") 3x. Я хотел бы что-то дедуплицировать этот вызов.

Однако, похоже, что с загрузчиком данных мне нужно передать массив ключей в мою пакетную функцию, и несколько запросов будут объединены в один вызов API.

Это заставляет меня сделать несколько предположений, которые мне не нравятся:

1.) Что у каждой службы, которую я вызываю, есть пакетный API (некоторые из тех, с которыми я имею дело, не имеют).

2.) Что делать, если несколько вызовов объединяются в 1 вызов API, и этот вызов не выполняется, поскольку 1 из элементов не был найден. Обычно я мог бы обработать это, возвращая ноль для этого поля, и это могло бы быть допустимым случаем. Однако теперь весь мой вызов может завершиться ошибкой, если пакетный API решит выдать ошибку, так как 1 элемент не был найден.

Есть ли в любом случае использовать dataloader с запросами с одним ключом.

1 Ответ

1 голос
/ 04 апреля 2020

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

Функция пакетной загрузки принимает массив ключей и возвращает Promise, который разрешается в массив значений или экземпляры Error.

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

Другими словами, ваша реализация пакетной функции может выглядеть примерно так:

async function batchFn (ids) {
  const result = await Promise.all(ids.map(async (id) => {
    try {
      const foo = await getFooById(id)
      return foo
    } catch (e) {
      // either return null or the error
    }
  }))
}

Стоит отметить, что также можно установить maxBatchSize на 1, чтобы эффективно отключить пакетирование. Однако это не меняет требований к реализации вашей пакетной функции - ей всегда нужно принимать массив идентификаторов и всегда возвращать массив значений / ошибок той же длины, что и массив идентификаторов.

...