是否可以从Java中的查询(字符串)访问 GraphQL选择集?
例如来自下面的字符串:
"{
data {
title
description
}
}"
获取字段列表:["data", "title", "description"]
答案 0 :(得分:1)
如果您只想直接从字符串中提取字段,则可以解析查询并递归遍历生成的文档以收集名称。
您可以这样解析查询:
Parser parser = new Parser();
Document document = parser.parseDocument(queryString);
Document
对象是解析为树结构的查询。你可以遍历它以提取你需要的东西。
如果您只需要在字段解析期间选择集合(例如,查看请求了哪些子选择,以便优化提取逻辑,例如触发SELECT title, description FROM ...
而不是SELECT * FROM ...
)那么&#39 ;更简单的方法是DataFetchingEnvironment
已经提供了对选择集的访问:
DataFetchingFieldSelectionSet selectionSet = dataFetchingEnv.getSelectionSet();
Map<String, List<Field>> fieldsByName = selectionSet.get();
如果您需要深入钻取一个级别,可以使用接受全局模式的DataFetchingFieldSelectionSet.contains
,例如parent/*/grandChild
并告诉您是否请求了这样的字段。
您还可以从Field
DataFetchingEnvironment
List<Field> getFields().get(0)
然后,您可以从中提取当前字段的子选择。如果存在潜在的条件选择(即当前字段是接口,则选择可能取决于实现,例如... on Impl { title }
),这最后一种方法才有意义。
答案 1 :(得分:1)
这对我有用,我使用了Parser来获取字段列表:
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());
}
});
}
}