spring-graphql icon indicating copy to clipboard operation
spring-graphql copied to clipboard

Do not ignore a DataFetcher with a DataFetcherFactories wrapper

Open kitkars opened this issue 3 years ago • 1 comments

schem.graphqls

directive @UpperCase on FIELD_DEFINITION

type Query{
    hello: String @UpperCase
}

QueryMapping

@QueryMapping
public Mono<String> hello(){
       return Mono.just("hello");
}

SchemaDirectiveWriting

    @Override
    public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition> environment) {
        DataFetcher<?> dataFetcher = DataFetcherFactories.wrapDataFetcher(environment.getFieldDataFetcher(), ((dataFetchingEnvironment, value) -> {
            return Mono.just("HELLO");
        }));
        return environment.setFieldDataFetcher(dataFetcher);
    }

I was expecting "HELLO" and but it returns this,

{
  "data": {
    "hello": "MonoJust"
  }
}

kitkars avatar Jul 15 '22 03:07 kitkars

DataFetherFactories supports a function to apply to the value of a CompletionStage. Spring for GraphQL applies similar decoration to support Reactor types. However, it ignores any DataFetchers under the graphql package, and that includes DataFetcherFactories.

I can add an exclusion for DataFetcherFactories but in general, if you want to support a directive for Reactor return types you will need to the wrapping yourself anyway. Something like this:

@Override
public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition> environment) {
	if (environment.getDirective("UpperCase") == null) {
		return environment.getElement();
	}
	DataFetcher<?> fieldDataFetcher = environment.getFieldDataFetcher();
	return environment.setFieldDataFetcher(dataFetchingEnvironment -> {
		Object value = fieldDataFetcher.get(dataFetchingEnvironment);
		if (value instanceof Mono) {
			return ((Mono<?>) value).map(s -> (s instanceof String ? ((String) s).toUpperCase() : s));
		}
		else if (value instanceof String) {
			return ((String) value).toUpperCase();
		}
		else {
			return value;
		}
	});
}

rstoyanchev avatar Aug 04 '22 11:08 rstoyanchev