访问 graphQL 查询的选择集
Access Selection Set of a graphQL query
是否可以从 Java 中的查询(字符串)访问 GraphQL 选择集?
例如下面的字符串:
"{
data {
title
description
}
}"
获取字段列表:["data", "title", "description"]
如果您只想直接从字符串中提取字段,您可以解析查询并递归遍历生成的文档以收集名称。
您可以这样解析查询:
Parser parser = new Parser();
Document document = parser.parseDocument(queryString);
Document
对象是解析为树结构的查询。你可以遍历它来提取你需要的东西。
如果您只需要在字段解析期间设置选择(例如,查看请求的 sub-selections,那么您优化获取逻辑,例如触发 SELECT title, description FROM ...
而不是 SELECT * FROM ...
) 有一个更简单的方法,因为 DataFetchingEnvironment
已经提供了对选择集的访问:
DataFetchingFieldSelectionSet selectionSet = dataFetchingEnv.getSelectionSet();
Map<String, List<Field>> fieldsByName = selectionSet.get();
如果你需要钻得比一层更深,你可以使用 DataFetchingFieldSelectionSet.contains
它接受一个 glob 模式,例如parent/*/grandChild
并告诉您是否请求了这样的字段。
您还可以从 DataFetchingEnvironment
:
获取当前 Field
List<Field> getFields().get(0)
然后您可以从那里提取当前字段的 sub-selection。最后一种方法只有在存在潜在的条件选择时才有意义(即当前字段是一个接口,因此选择可能取决于实现,例如 ... on Impl { title }
)。
这对我有用,我使用解析器来获取字段列表:
private static List<Field> parseGraphQLQuery(String query) {
List<Field> fieldList = new ArrayList<Field>();
Parser parser = new Parser();
Document doc = parser.parseDocument(query);
List<Definition> definitionList = doc.getDefinitions();
definitionList.forEach( (item) -> {
if (item instanceof OperationDefinition) {
OperationDefinition operationDefinition = (OperationDefinition) item;
SelectionSet selectionSet = operationDefinition.getSelectionSet();
extractQueryElements(fieldList, selectionSet);
}
});
return fieldList;
}
/**
* Add fields to field name list
* @param fieldNameList
* @param selectionSet
*/
private static void extractQueryElements(List<Field> fieldNameList, SelectionSet selectionSet) {
if (selectionSet != null && selectionSet.getSelections() != null) {
selectionSet.getSelections().forEach( (selection) -> {
if (selection instanceof Field) {
Field field = (Field) selection;
fieldNameList.add(field);
extractQueryElements(fieldNameList, field.getSelectionSet());
}
});
}
}
是否可以从 Java 中的查询(字符串)访问 GraphQL 选择集?
例如下面的字符串:
"{
data {
title
description
}
}"
获取字段列表:["data", "title", "description"]
如果您只想直接从字符串中提取字段,您可以解析查询并递归遍历生成的文档以收集名称。
您可以这样解析查询:
Parser parser = new Parser();
Document document = parser.parseDocument(queryString);
Document
对象是解析为树结构的查询。你可以遍历它来提取你需要的东西。
如果您只需要在字段解析期间设置选择(例如,查看请求的 sub-selections,那么您优化获取逻辑,例如触发 SELECT title, description FROM ...
而不是 SELECT * FROM ...
) 有一个更简单的方法,因为 DataFetchingEnvironment
已经提供了对选择集的访问:
DataFetchingFieldSelectionSet selectionSet = dataFetchingEnv.getSelectionSet();
Map<String, List<Field>> fieldsByName = selectionSet.get();
如果你需要钻得比一层更深,你可以使用 DataFetchingFieldSelectionSet.contains
它接受一个 glob 模式,例如parent/*/grandChild
并告诉您是否请求了这样的字段。
您还可以从 DataFetchingEnvironment
:
Field
List<Field> getFields().get(0)
然后您可以从那里提取当前字段的 sub-selection。最后一种方法只有在存在潜在的条件选择时才有意义(即当前字段是一个接口,因此选择可能取决于实现,例如 ... on Impl { title }
)。
这对我有用,我使用解析器来获取字段列表:
private static List<Field> parseGraphQLQuery(String query) {
List<Field> fieldList = new ArrayList<Field>();
Parser parser = new Parser();
Document doc = parser.parseDocument(query);
List<Definition> definitionList = doc.getDefinitions();
definitionList.forEach( (item) -> {
if (item instanceof OperationDefinition) {
OperationDefinition operationDefinition = (OperationDefinition) item;
SelectionSet selectionSet = operationDefinition.getSelectionSet();
extractQueryElements(fieldList, selectionSet);
}
});
return fieldList;
}
/**
* Add fields to field name list
* @param fieldNameList
* @param selectionSet
*/
private static void extractQueryElements(List<Field> fieldNameList, SelectionSet selectionSet) {
if (selectionSet != null && selectionSet.getSelections() != null) {
selectionSet.getSelections().forEach( (selection) -> {
if (selection instanceof Field) {
Field field = (Field) selection;
fieldNameList.add(field);
extractQueryElements(fieldNameList, field.getSelectionSet());
}
});
}
}