Как использовать API отдельных запросов GraphQL, чтобы получить список? - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь получить список моделей.

Сначала я создал API запроса модели.И теперь я хочу получить список, предоставив ids.

Я знаю, что могу использовать Promise.all на getModelById и выполнить некоторую обработку для каждого полученного мной результата.

НоЕсть ли способ повторно использовать API запроса отдельной модели?Спасибо

const ModelType = new GraphQLObjectType({
  name: 'Model',
  fields: {
    id: { type: GraphQLString },
    // ...
  }
});

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: () => ({
    model: {
      type: ModelType,
      args: {
        id: { type: GraphQLString }
      },
      resolve(parentValue, args) {
        const { id } = args;
        return getModelById(id).then(model => doSomeProcessing(model));
      }
    },

    models: {
      type: new GraphQLList(ModelType),
      args: {
        ids: { type: new GraphQLList(GraphQLString) }
      },
      resolve(parentValue, args) {
        const { ids } = args;
        // here I know I can use Promise.all on getModelById and do my doSomeProcessing again for each result I got,
        // but is there a way to reuse the model query above? Thanks
      }
    }
  })
});

1 Ответ

0 голосов
/ 14 ноября 2018

Вы не можете ссылаться на существующий распознаватель внутри другого распознавателя. Единственный способ повторно использовать логику - это абстрагировать ее в отдельную функцию, которая вызывается обоими преобразователями. Например:

const getProcessedModelById = (id) => {
  return getModelById(id).then(model => doSomeProcessing(model))
}

// model
resolve(parentValue, args) {
  return getProcessedModelById(args.id)
}

// models
resolve(parentValue, args) {
  return Promise.all(args.ids.map(id => getProcessedModelById(args.id)))
}

В зависимости от вида обработки, который вы выполняете на модели, это может быть возможно сделать через средства распознавания полей типа Model. Допустим, ваш тип Model имеет два поля - firstName и lastName, но ваша модель возвращает одно поле с именем name. Ваш doSomeProcessing просто берет это имя и разбивает его на firstName и lastName:

function doSomeProcessing (model) {
  const names = model.name.split(' ')
  return { firstName: names[0], lastName: names[1] }
}

Вместо этого ваши распознаватели могут просто вернуть все, что вернет getModelById. Затем вы можете инкапсулировать логику «обработки» в определителе каждого поля:

// firstName field
resolve (parentValue) {
  return parentValue.name.split(' ')[0]
}

// lastName field
resolve (parentValue) {
  return parentValue.name.split(' ')[1]
}

Преимущество этого подхода в том, что «обработка» фактически не произойдет, если клиент не запросит это поле. В этом очень простом примере разрешение поля lastName не дорого, но это не всегда так. Он также очень аккуратно инкапсулирует логику для полей, которые получены из нижележащего уровня данных. Тем не менее, он также может оказаться более дорогим (представьте, например, что вызов split сам по себе был дорогим ... теперь мы вызываем этот метод дважды, а не один раз).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...