访问 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());
            } 
        });
    }
}