Search code examples
graphqlgraphql-javagraphql-java-tools

getting requested fields on resolver level from graphql


Model of book from graphql schema

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

So I am having this resolver for Book

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);
    }
}

It works fine.

Now lets assume that I am using this graphql query, which is requesting only one field of the Book

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

The question is, how to get info on the bookById method level about the fields which are requested (in this case only the name field)? Is this even possible with the GraphQLQueryResolver concept?

Example with 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);
        };
    }

This works quite well, but I am interested in the Resolver way. Is it possible?


Solution

  • You can add the dataFetchingEnvironment as a parameter and get the list of requested field names using that.

    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);
    }
    

    Just to be clear, for the resolver you created and given query request, the response will have only name and no other fields.