Получение полной строки запроса изнутри распознавателя

Я новичок в nodejs и сервере Apollo, так что не осуждайте меня.

Проблема звучит точно так же, как заголовок: «как получить строку graphql внутри функции распознавателя?».

На самом деле у вас есть четыре аргумента в каждом распознавателе: родитель, аргументы, контекст, информация. Немного информации здесь: https://www.apollographql.com/docs/apollo-server/essentials/data#type-signature

Я решил написать функцию, которая собирает вложенный объект внутри контекста для перегенерации строки запроса. Зачем мне это нужно? Хороший вопрос. Я пишу микросервис, поэтому, когда я получаю вложенный запрос к полю, которое находится за пределами текущего микросервиса, я передаю запрос по http.

Мой резольвер:

eventByID: async (root, args, context) => {
const event = await EventModel.findById(root.id);
event.creator = await nestedContextProvider(context, 'creator', event.creator);
return eventFascade(event); //just fascade for object - nothing serious

},

Он ссылается на nestedContextProvider для решения вложенного контекста:

const nestedQueryTraverser = (nestedQueryArray) => {
const nestedQueryTraversed = nestedQueryArray.selectionSet.selections.map(element => (
element.selectionSet === undefined
  ? element.name.value
  : `${element.name.value}{${nestedQueryTraverser(element)}}`));
return nestedQueryTraversed;
};

const nestedContextProvider = async (context, checkField, ID) => {
if (context.operation.selectionSet.selections[0].selectionSet.selections
.find(selector => selector.name.value === checkField)) {
let nestedFieldsArr = context.operation.selectionSet.selections[0]
  .selectionSet.selections.find(selector => selector.name.value === checkField);
nestedFieldsArr = nestedQueryTraverser(nestedFieldsArr);
const a = (await users(ID, nestedFieldsArr));
return a.data.usersByIDs[0];
}
return ID;
};

Так что это работает для меня, но я знаю, что должно быть лучшее решение.

Есть идеи?

FWIW, вы можете захотеть создать исполняемые, удаленные схемы, а затем сшивание их вместе, вместо того, чтобы самостоятельно делегировать разрешение поля.

Daniel Rearden 26.04.2019 14:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
728
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пакет graphql включает функцию print, которая принимает любой AST и возвращает строковое представление, поэтому вы можете сделать что-то вроде этого:

const { print } = require('graphql')

function anyResolver (parent, args, context, info) {
  const operationString = print(info.operation)
  // Fragments are not included in the operation, but we still need to print
  // them otherwise our document will reference non-existing fragments
  const fragmentsString = Object.keys(info.fragments)
    .map(fragmentName => print(info.fragments[fragmentName]))
    .join('\n\n')
  const documentString = `${operationString}\n\n${fragmentsString}`
}

Здорово! Кстати, нужно признать, что если у вас есть контекстная директива в экземпляре new ApolloServer, вы будете иметь info в третьем, а не в четвертом аргументе резольвера. Но print из graphql делает свою работу. Спасибо Даниил!

Artsem mardvinau 26.04.2019 15:09

Другие вопросы по теме