jooby
jooby copied to clipboard
Allow extension to provide handlers for routes' return type
It would be cool to allow extensions to provide handlers for return types. Example : I want to add first party support for reactive Mutiny types (Uni<T> and Multi<T>). Some links : https://github.com/smallrye/smallrye-mutiny & https://smallrye.io/smallrye-mutiny.
By taking a look at io.jooby.Pipeline, this looks hardcoded for core types and most common reactive libraries types but this looks pretty straightforward :
// Single:
Optional<Class> single = loadClass(loader, "io.reactivex.Single");
if (single.isPresent()) {
if (single.get().isAssignableFrom(type)) {
return single(mode, route, executor);
}
}
// and
private static Handler single(ExecutionMode mode, Route next, Executor executor) {
return next(mode, executor,
new DetachHandler(decorate(next, new RxSingleHandler(next.getPipeline()))),
false);
}
Offloading this logic into extensions would permit a cleaner way to add support for other types by requiring the user to install a module and removing those loadClass
calls (less reflection is good). This would also allow to remove the core module dependencies related to those.
Providing an api similar to MessageEncoder/MessageDecoder would be nice. From jooby-jackson :
application.decoder(MediaType.json, this);
Proposition :
application.monadResolver(Single.class, this);
Is it something you can consider ? Maybe you already thought of it ?
Like it. I want to remove those loadClass checks from core and make this more modular (like it was in 1.x). The reason why I added like this was to simplify integration.
But in general:
- remove the return type concept (bc it is based on reflection)
- move the reactive types to his own module
In 1.x we do have something like:
use(new Rx());
get("/", () -> Observable.from("reactive programming in jooby!"));
Where Rx
was an extension that install a filter/decorator
Just realize that there is an API for custom types: https://www.javadoc.io/doc/io.jooby/jooby/latest/io/jooby/ResponseHandler.html
MyExtension {
install(Jooby app) {
app.responseHandler(...);
}
}
Rocker template engine uses a custom response handler: https://github.com/jooby-project/jooby/blob/2.x/modules/jooby-rocker/src/main/java/io/jooby/rocker/RockerModule.java#L45
Still we should improve and make it better:
- reflection free
- extract reactive types to his own module
I think the only reactive support that should be provided is JDK 9 Flow. All the reactive libraries have bridges to JDK 9 Flow and it seems reasonable to support a data structure that is builtin. CompletableFuture
for singles and Flow.Publisher
for streams is good enough for OOB.
However you still need to move it out to its own module since Flow requires 9.