从解析器内部获取完整的查询字符串

时间:2019-04-26 10:20:01

标签: node.js graphql apollo apollo-server

我是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;
};

所以它对我有用,但是我知道必须有更好的解决方案。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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}`
}