graphqlgraphql-js

How to get requested fields inside GraphQL resolver?


I am using graphql-tools. After receiving a GraphQL query, I execute a search using ElasticSearch and return the data.

However, usually the requested query includes only a few of the possible fields, not all. I want to pass only the requested fields to ElasticSearch. First, I need to get the requested fields.

I can already get the whole query as a string. For example, in the resolver,

const resolvers = {
  Query: {
    async user(p, args, context) {
      //can print  query as following
      console.log(context.query)                
    }
    .....
  }
}

It prints as

query User { user(id:"111") { id  name address } }

Is there any way to get the requested fields in a format like

{ id:"",  name:"", address:"" }

Solution

  • In graphql-js resolvers expose a fourth argument called resolve info. This field contains more information about the field.

    From the GraphQL docs GraphQLObjectType config parameter type definition:

    // See below about resolver functions.
    type GraphQLFieldResolveFn = (
      source?: any,
      args?: {[argName: string]: any},
      context?: any,
      info?: GraphQLResolveInfo
    ) => any
    
    type GraphQLResolveInfo = {
      fieldName: string,
      fieldNodes: Array<Field>,
      returnType: GraphQLOutputType,
      parentType: GraphQLCompositeType,
      schema: GraphQLSchema,
      fragments: { [fragmentName: string]: FragmentDefinition },
      rootValue: any,
      operation: OperationDefinition,
      variableValues: { [variableName: string]: any },
    }
    

    In the fieldNodes field you can search for your field and get the selectionSet for the particular field. From here it gets tricky since the selections can be normal field selections, fragments or inline fragments. You would have to merge all of them to know all fields that are selected on a field.