Я новичок в 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;
};
Так что это работает для меня, но я знаю, что должно быть лучшее решение.
Есть идеи?





Пакет 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 делает свою работу. Спасибо Даниил!
FWIW, вы можете захотеть создать исполняемые, удаленные схемы, а затем сшивание их вместе, вместо того, чтобы самостоятельно делегировать разрешение поля.