从解析器内部获取完整的查询字符串
Getting complete query string from inside of resolver
我是 nodejs 和 apollo 服务器的新手,所以不要评判我。
问题听起来与标题完全一样:"how to get graphql string inside resolver function?"。
实际上,每个解析器中都有四个参数:parent、args、context、info。
这里有一些信息:https://www.apollographql.com/docs/apollo-server/essentials/data#type-signature
我决定编写一个函数,它收集嵌套的 object 内部上下文以重新生成查询字符串。为什么我需要它?好问题。我正在编写微服务,所以当我对当前微服务之外的字段进行嵌套查询时,我通过 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 和 returns 字符串表示,所以你可以这样做:
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}`
}
我是 nodejs 和 apollo 服务器的新手,所以不要评判我。
问题听起来与标题完全一样:"how to get graphql string inside resolver function?"。
实际上,每个解析器中都有四个参数:parent、args、context、info。 这里有一些信息:https://www.apollographql.com/docs/apollo-server/essentials/data#type-signature
我决定编写一个函数,它收集嵌套的 object 内部上下文以重新生成查询字符串。为什么我需要它?好问题。我正在编写微服务,所以当我对当前微服务之外的字段进行嵌套查询时,我通过 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 和 returns 字符串表示,所以你可以这样做:
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}`
}