javagraphqlgraphql-javagraphql-spqrgraphql-spqr-spring-boot-starter

Get Original Field Name on GraphQL


I'm using https://github.com/leangen/graphql-spqr with spring-boot java application. I can reach to alias name easily but how can I reach to original fieldName?

 class Food {
   @GraphQLQuery(name = "aliasNameX", description = "A food's name")
   private String originalName; 
   ...
 }

  ....

  @GraphQLQuery(name = "foods") // READ ALL
   @Override
   public List<Food> getFoods(@GraphQLEnvironment ResolutionEnvironment env) {
       DataFetchingFieldSelectionSet selectionSet = env.dataFetchingEnvironment.getSelectionSet();
       List<SelectedField> fields = selectionSet.getFields();
       for (SelectedField f: fields)
       {
           System.out.println(f.getName());
       }
       return foodRepository.findAll();
   }

When I run this code, Output looks like with alias fields: "aliasNameX", ..., but I need original name like "originalName". Is there a way to do it?

Solved, according to:

https://github.com/leangen/graphql-spqr/issues/381


Solution

  • Posting my original answer here as well.

    You want the underlying field names, but from a level above. Still possible, but ugly :(

    for (SelectedField selectedField : env.dataFetchingEnvironment.getSelectionSet().getImmediateFields()) {
        Optional<Operation> operation = Directives.getMappedOperation(selectedField.getFieldDefinition());
        String javaName = operation.map(op -> ((Member) op.getTypedElement().getElement()).getName()).orElse(null);
    }
    

    Be very careful though. If there's more than one Java element exposed per GraphQL field, getTypedElement().getElement() will explode. So to be sure you'd have to call getTypedElement().getElements() (plural) instead and decide what to do. ClassUtils#getPropertyMembers might also be useful, or the ClassUtils.findXXX family of methods.

    You'd basically have to do this:

    List<AnnotatedElement> elements = getTypedElement().getElements();
    //Look for a field and use its name
    Optional<String> field = Utils.extractInstances(elements, Field.class).findFirst().map(Field::getName);
    //Look for a getter and find its associated field name
    Optional<String> getter = Utils.extractInstances(elements, Method.class).findFirst().map(ClassUtils::getFieldNameFromGetter);
    

    This API might have to change in future, as SDL-based tools are proliferating, so complex directives like the ones SPQR is using are causing problems...