如何在 GraphQL 解析器中获取请求的字段?
How to get requested fields inside GraphQL resolver?
我正在使用 graphql-tools
。收到 GraphQL 查询后,我使用 ElasticSearch 和 return 数据执行搜索。
但是,请求的查询通常只包括一些可能的字段,而不是全部。我只想将请求的字段传递给 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:"" }
在 graphql-js 解析器中公开了第四个参数,称为解析信息。该字段包含有关该字段的更多信息。
来自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
可以是普通字段选择、片段或内联片段。您必须合并所有这些才能知道在一个字段上选择的所有字段。
有一个 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']
},
};
与 graphql-java
类似,您可以通过使用 myGetUsersResolverMethod(... DataFetchingEnvironment env)
扩展字段参数来执行相同的操作。
这个 DataFetchingEnvironment
会为你注入,你可以遍历这个 DataFetchingEnvironment
对象作为 graph
/查询的任何部分。
此对象可让您更多地了解正在获取的内容以及已提供的参数。
示例:
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 fetchers for Building efficient data fetchers by looking ahead
寻找更有效的方法来做到这一点
我正在使用 graphql-tools
。收到 GraphQL 查询后,我使用 ElasticSearch 和 return 数据执行搜索。
但是,请求的查询通常只包括一些可能的字段,而不是全部。我只想将请求的字段传递给 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:"" }
在 graphql-js 解析器中公开了第四个参数,称为解析信息。该字段包含有关该字段的更多信息。
来自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
可以是普通字段选择、片段或内联片段。您必须合并所有这些才能知道在一个字段上选择的所有字段。
有一个 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']
},
};
与 graphql-java
类似,您可以通过使用 myGetUsersResolverMethod(... DataFetchingEnvironment env)
扩展字段参数来执行相同的操作。
这个
DataFetchingEnvironment
会为你注入,你可以遍历这个DataFetchingEnvironment
对象作为graph
/查询的任何部分。此对象可让您更多地了解正在获取的内容以及已提供的参数。
示例:
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 fetchers for Building efficient data fetchers by looking ahead
寻找更有效的方法来做到这一点