ResolverInterceptors currently run directly around the underlying method invocation. This is intuitive, as the the result of proceed(...) will be the whatever the method returned, unmodified. However, it is sometimes useful to obtain the converted result (the result after OutputConverters have been applied to it). A good use-case for this is wrapping the already processed result (or, more often, the exception) into a DataFetcherResult, or running the underlying method asynchronously, turning the result into a CompletableFuture.
This can all be achieved using the existing method interception facility, it is only necessary to clearly demarcate when each interceptor is supposed to run in relation to output conversion.
Changes:
ResolverInterceptorFactory will get a new method: List<ResolverInterceptor> getOuterInterceptors(ResolverInterceptorFactoryParams params). It will have a default implementation, for backwards compatibility. Interceptors returned by this method will run around output conversion.
GraphQLSchemaGenerator will get new convenience methods withOuterResolverInterceptors(...)
Example:
public class TestService {
@GraphQLQuery
// Returns a result that normally gets converted, e.g. a Stream is converted to a List on the way out
public Stream<String> stream() {
return Stream.of("aaa", "bbb");
}
}
public class TestInterceptor implements ResolverInterceptor {
@Override
public Object aroundInvoke(InvocationContext context, Continuation continuation) throws Exception {
Object result = continuation.proceed(context);
System.out.println(result instanceof Stream ? "Got Stream" : "Got List");
return result;
}
}
generator
.withOperationsFromSingleton(new TestService())
.withResolverInterceptors(new TestInterceptor()) // This TestInterceptor will print "Got Stream"
.withOuterResolverInterceptors(new TestInterceptor()) // This TestInterceptor will print "Got List"
ResolverInterceptor
s currently run directly around the underlying method invocation. This is intuitive, as the the result ofproceed(...)
will be the whatever the method returned, unmodified. However, it is sometimes useful to obtain the converted result (the result afterOutputConverter
s have been applied to it). A good use-case for this is wrapping the already processed result (or, more often, the exception) into aDataFetcherResult
, or running the underlying method asynchronously, turning the result into aCompletableFuture
.This can all be achieved using the existing method interception facility, it is only necessary to clearly demarcate when each interceptor is supposed to run in relation to output conversion.
Changes:
ResolverInterceptorFactory
will get a new method:List<ResolverInterceptor> getOuterInterceptors(ResolverInterceptorFactoryParams params)
. It will have a default implementation, for backwards compatibility. Interceptors returned by this method will run around output conversion.GraphQLSchemaGenerator
will get new convenience methodswithOuterResolverInterceptors(...)
Example:
See Javadoc on ResolverInterceptorFactory and the related tests for more detailed examples (applying interceptors only to specific methods etc).