如何在GraphQL解析器中获取请求的字段?

时间:2017-12-28 09:23:22

标签: graphql graphql-js

我正在使用graphql-tools。收到GraphQL查询后,我使用ElasticSearch执行搜索并返回数据。

但是,通常请求的查询仅包含一些可能的字段,而不是全部。我想只将请求的字段传递给ElasticSearch。 首先,我需要获取所请求的字段。

我已经可以将整个查询作为字符串了。例如,在解析器中,

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

打印为

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

有没有办法以

之类的格式获取请求的字段
{ id:"",  name:"", address:"" }

3 个答案:

答案 0 :(得分:5)

在graphql-js解析器中公开了一个名为resolve info的第四个参数。该字段包含有关该字段的更多信息。

GraphQL docs GraphQLObjectType配置参数类型定义:

// 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 },
}

fieldNodes字段中,您可以搜索您的字段并获取特定字段的selectionSet。从这里开始它变得棘手,因为selections可以是正常的字段选择,片段或内联片段。您必须合并所有这些以了解在字段上选择的所有字段。

答案 1 :(得分:4)

在解析器中传递了info个对象作为第4个参数。此参数包含您要查找的信息。

使用库graphql-fields来帮助您解析graphql查询数据会很有帮助:

const graphqlFields = require('graphql-fields');

const resolvers = {
  Query: {
    async user(_, args, context, info) {
      const topLevelFields = graphqlFields(info);
      console.log(Object.keys(topLevelFields)); // ['id', 'name', 'address']
    },
};

答案 2 :(得分:0)

类似地,对于graphql-java,您可以通过使用myGetUsersResolverMethod(... DataFetchingEnvironment env)扩展字段参数来执行相同的操作。

  • DataFetchingEnvironment将为您注入,您可以遍历此DataFetchingEnvironment对象以查找graph / query的任何部分。

  • 该对象使您可以了解有关所获取的内容和提供的参数的更多信息。

示例:

    public List<User> getUsers(final UsersFilter filter, DataFetchingEnvironment env) {

    DataFetchingFieldSelectionSet selectionSet = env.getSelectionSet();
    selectionSet.getFields(); // <---List of selected fields
    selectionSet.getArguments(); // <--- Similarly but MAP
    ...

    }

实际上,您可能暗示着要进行数据提取。上面的内容应该可以使您对请求的字段有足够的了解,并且可以从那里开始手动调整下游呼叫。但是您也可以通过using the data fetchersBuilding efficient data fetchers by looking ahead

寻找一种更有效的方法