0

是否可以从 Java 中的查询(字符串)访问GraphQL 选择集?

例如从下面的字符串:

"{
    data {
        title
        description
    }
}"

获取字段列表:["data", "title", "description"]

4

2 回答 2

1

如果您的意思是直接从字符串中提取字段,您可以解析查询并递归遍历生成的文档以收集名称。

您可以这样解析查询:

Parser parser = new Parser();
Document document = parser.parseDocument(queryString);

Document对象是解析成树结构的查询。你可以遍历它来提取你需要的东西。

如果您在字段解析期间只需要选择集(例如,查看请求了哪些子选择,以便优化获取逻辑,例如触发 aSELECT title, description FROM ...而不是 a SELECT * FROM ...),则有一种更简单的方法,因为DataFetchingEnvironment已经提供了对选择集的访问:

DataFetchingFieldSelectionSet selectionSet = dataFetchingEnv.getSelectionSet();
Map<String, List<Field>> fieldsByName = selectionSet.get();

如果您需要深入一层以上,您可以使用DataFetchingFieldSelectionSet.containswhich 接受 glob 模式,例如parent/*/grandChild并告诉您是否请求了这样的字段。

您还可以Field从以下位置获取电流DataFetchingEnvironment

List<Field> getFields().get(0)

从那里您可以提取当前字段的子选择。最后一种方法只有在存在潜在的条件选择时才有意义(即当前字段是一个接口,因此选择可能取决于实现,例如... on Impl { title })。

于 2018-02-26T15:29:25.423 回答
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());
            } 
        });
    }
}
于 2018-03-01T09:41:48.710 回答