Redpipe is a Web Framework that unites the power and versatility of Eclipse Vert.x, the conciseness of
JAX-RS (with Resteasy),
and the non-blocking reactive composition of RxJava.
The main idea is that with Redpipe you write your endpoints in JAX-RS, using RxJava composition if you want, and underneath
it all, Vert.x is running the show and you can always access it if you need it.
Redpipe is opinionated, favors convention over configuration, and lets you combine the following technologies easily to
write reactive web applications:
Typically, instead of making a blocking call, asynchronous APIs will let you register a callback to invoke when
the action is done. But callbacks are error-prone and do not compose well.
The Promise model was introduced to
abstract over callbacks and asynchronous computations, where a Promise represents a producer of a value that
you can listen for, and be notified when the value is produced (we call that resolving a Promise).
RxJava is an implementation of the Promise model with support for single-value Promises
multiple-value Promise streams (Observable).
The idea of Redpipe is that you can either return normal values from your methods (if your code does not
need to block), or RxJava promises (if it does), which Redpipe will register on, and be notified when the
promises resolve and forward the resolved values to the client.
Out of the box, we support RxJava’s Single
and Observable, Completable and Maybe types for both RxJava 1 and 2,
although use of RxJava 2 is recommended because RxJava 1 is deprecated.
If your resource returns a Single<T>, the T will be sent to your client asynchronously as if you
returned it directly. In particular, standard and custom
apply as soon as the Single is resolved, as do
If your resource returns an Observable<T>:
By default, every item will be collected, and once complete, assembled in a List<T> and treated
as if your method had returned it directly (standard and custom body writers and interceptors apply
If you annotate your method with @Stream (from org.jboss.resteasy.annotations), then every item
will be sent to the client as soon as it is produced (again, via standard and custom body writers).
This is mostly useful for streaming bytes, buffers, or strings, which can be split up and buffered.
If you annotate your method with @Produces(MediaType.SERVER_SENT_EVENTS), then every item will
be sent to the client over
(SSE). As always, standard and custom body writers
are called to serialise your entities to events.
If your resource returns a Completable, an HTTP Response with status code 204 will be returned once the completable
If your resource returns a Maybe<T>, then the following response will be sent asynchronously once the maybe is
If the maybe is empty: an empty HTTP response using HTTP status code 404 indicating the resource has not been found
If the maybe has been fulfilled with an object of type T: an HTTP response with status code 200,
using the proper MessageBodyWriter<T>
The optional module redpipe-fibers allows you to write your reactive code in fibers, which are
light-weight threads, also known as coroutines, while interacting seamlessly with RxJava.
Consider the following traditional RxJava code to forward the result of two web service invocations:
Rather than composing sequential Single values, you can write a fiber that can
await those values in what now looks like sequential code:
A fiber, here, is also a Single which can be integrated with the rest of your RxJava
operations, and it can await RxJava Single values to obtain their resolved value.
You can call await from any fiber body, or from any method annotated with @Suspendable.
You need to import the following module in order to use fibers:
And also the following Maven build plug-in to set-up your fibers at compile-time:
In order to get URIs that map to resource methods, you can use the redpipe routing module:
With this module, you can simply get a URI for a resource method HelloResource.hello by calling
the Router.getURI() method and passing it a reference to your resource method and any required
Within templates you can use the context.route method which takes a string literal pointing to your
resource method, and any required parameters:
You can either declare your JAX-RS resources and providers when instantiating the Server (as shown
above), or you can use two options to scan your packages to discover them.
If you include this dependency, fast-classpath-scanner
will be used to scan your classpath for resources and providers:
Unless you call Server.start() with a JsonObject configuration to override it,
the conf/config.json file will be loaded and used for configuration.
In addition to the standard Vertx options,
these are the configuration options available:
Jdbc Url to use for connections to the database.
Jdbc driver class.
Maximum pool size for database connections.
Http port to bind to.
Http host to bind to.
0.0.0.0 (all interfaces)
For the `redpipe-fast-classpath-scanner` module
List of packages to scan for JAX-RS resources and providers.
You can access the current configuration in your application via the AppGlobals.getConfig() method.
On top of optional CDI support, JAX-RS supports injection of certain resources via the @Context annotation
on method parameters and members. Besides the regular JAX-RS resources, the following resources can be
Injectable global resources
The Vert.x instance (Also available as RxJava 1 & core).
A global context object.
Injectable per-request resources
The Vert.x Web RoutingContext (Also available as RxJava 1 & core).
The Vert.x request (Also available as RxJava 1 & core).
The Vert.x response (Also available as RxJava 1 & core).
The Vert.x AuthProvider instance, if any (defaults to null) (Also available as RxJava 1 & core).
The Vert.x User, if any (defaults to null) (Also available as RxJava 1 & core).
The Vert.x Web Session instance, if any (defaults to null) (Also available as RxJava 1 & core).
An SQLConnection (Also available as RxJava 1 & core).
True if there is a current user and he has that permission.
We support the following plugable template engines, which you just have to add a dependency on:
In order to declare templates, simply place them in the src/main/resources/templates folder. For
example, here’s our src/main/resources/templates/index.ftl template:
In order to return a rendered template, just return them from your resource, directly or as a Single:
Writing your own template renderer
You can write your own template renderer by declaring a META-INF/services/net.redpipe.engine.template.TemplateRenderer file in your
src/main/resources folder, containing the name of the class that extends the
You can declare and inject service records using the following optional module:
Use the @ServiceName annotation to declare a service:
The same annotation can be used to look up services:
By default, if running on Kubernetes, Kubernetes services will be imported and available.
Note that services declared using @ServiceName will not be exported to Kubernetes, but
you can declare them in your build using Fabric8.
You can write plugins by declaring a META-INF/services/net.redpipe.engine.spi.Plugin file in your
src/main/resources folder, containing the name of the class that extends the
From there you can hook into various parts of the application (start-up, requests…).
And then configure your pom.xml so that it creates a fat-jar with the proper merging of
META-INF/services files, and pointing to your Main class:
Then, just follow the official guidelines by
pushing your code to GitHub and starting an image with it. You can even try our sample app at
https://github.com/FroMage/redpipe-openshift-helloworld.git (no context dir).
Alternately, you can use Fabric8 to build and deploy your module by adding this to your
Declaring services with Fabric8
You can declare Kubernetes services, labels and annotations with this configuration:
Run your WebApp with Maven
This is a pom.xml sample to easily run your project. Just run mvn install exec:java