从 graphql 获取解析器级别的请求字段

getting requested fields on resolver level from graphql

来自 graphql 模式的书籍模型

type Book {
  id: ID
  name: String
  pageCount: Int
  author: Author
}

所以我有这个书的解析器

public class BookResolver implements BookByIdQueryResolver, GraphQLQueryResolver {
    private final MockRepository mockRepository;

    public BookResolver(MockRepository mockRepository) {
        this.mockRepository = mockRepository;
    }

    @Override
    public BookTO bookById(String id) {
        return mockRepository.getBookById(id);
    }
}

它工作正常。

现在假设我正在使用这个 graphql 查询,它只请求 Book 的一个字段

{
  bookById(id: "someId") {
    name
  }
}

问题是,如何在 bookById 方法级别获取有关所请求字段的信息(在本例中仅为名称字段)?这甚至可以用 GraphQLQueryResolver 概念实现吗?

dataFetcher 示例

public DataFetcher getBookByIdDataFetcher() {
        return dataFetchingEnvironment -> {
            String bookId = dataFetchingEnvironment.getArgument("id");
            List<SelectedField> requestedFields = dataFetchingEnvironment.getSelectionSet()
                    .getFields()
                    .stream()
                    .collect(Collectors.toList());
            return books
                    .stream()
                    .filter(book -> book.get("id").equals(bookId))
                    .findFirst()
                    .orElse(null);
        };
    }

这很好用,但我对 Resolver 方式很感兴趣。可能吗?

您可以将 dataFetchingEnvironment 添加为参数,并使用它获取请求的字段名称列表。

public BookTO bookById(String id, DataFetchingEnvironment dataFetchingEnvironment) {

    List<SelectedField> requestedFields = dataFetchingEnvironment.getSelectionSet()
                .getFields()
                .stream()
                .collect(Collectors.toList());
    // Use this for your use cases


    return mockRepository.getBookById(id);
}

需要说明的是,对于您创建并给出查询请求的解析器​​,响应将只有名称而没有其他字段。

我尝试了 Mat G 发布的解决方案,但它对我不起作用。对我有用的是:

public BookTO bookById(String id, DataFetchingEnvironment env) throws Exception {
        
        List<String> arguments = env.getField()
                .getSelectionSet()
                .getSelections()
                .parallelStream()
                .map(Field.class::cast)
                .map(Field::getName)
        .collect(Collectors.toList());
        
        // Query using the arguments
        return this.someService.getbookById(id, arguments);
    }