Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting complete query string from inside of resolver

I'm new to nodejs and apollo server, so don't judge me.

Problem sounds exactly same as title: "how to get graphql string inside resolver function?".

Actually, you have four args in every resolver: parent, args, context, info. Some info here: https://www.apollographql.com/docs/apollo-server/essentials/data#type-signature

I made my mind to write function, that gathers nested object inside context to regenerate query string. Why I need it? Good question. I'm writing microservice, so when i got nested query to field which is outside from current microservice I pass query by http.

My resolver:

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

It refers to nestedContextProvider for solving nested context:

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

So it works for me, but I know there must be better solution.

Any ideas?

like image 389
Artsem mardvinau Avatar asked Oct 14 '25 18:10

Artsem mardvinau


1 Answers

The graphql package includes a print function that takes any AST and returns the string representation, so you can do something like this:

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}`
}
like image 120
Daniel Rearden Avatar answered Oct 17 '25 08:10

Daniel Rearden



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!