users@jax-rs-spec.java.net

[jax-rs-spec users] Reactive API

From: Markus KARG <markus_at_headcrashing.eu>
Date: Wed, 10 Dec 2014 23:46:52 +0100

Santiago,

you asked for statements on the reactive paradigm w.r.t. JAX-RS. I'd like to
chime in here, as I already sent a proposal to you by private mail recently
which was not published so far. It is fair to begin again from the start, so
all experts have the same page to start.

The reactive paradigm (see Reactive Manifesto,
http://www.reactivemanifesto.org/) is rather popular these days, as it makes
software simply better, and it makes programming better software simpler, at
the same time. Having worked with reactive APIs for a few months, I really
love the simplicity to express dependend / mapped events like "when stock
ticker reports a price lower than last reported limit, then inform any
interested clients" in one single perfectly clean and readable code line!
Projected to JAX-RS, reactive programs would allow to declare / predefine
event-driven process chains (EPC) once ("fire and forget" solution), while
some kind of state engine is free to implement the actual way to "play" that
predefined paths later when the particular events actually do arise (again
and again, without the need to write a loop). This offers perfectly scalable
and consistent solutions to any event-driven problems. While these problems
historically are mostly found in GUIs, it more and more becomes obvious that
RESTful applications deal with the same need: scalable, event-driven
scenarios.

While the original JSR 370 charter proposes use of reactive programming for
clients only, I'd like to suggest not to narrow our vision on client only. I
do see good reasons to support reactive programming on the server side also.
But let's start with client:

Looking at the evolutions in the field of web technologies, with the advent
of SSE, WebSockets, etc. there is a shift from HTTP's historical
request-response pattern to a request-response initiation phase followed by
a list of asynchronously received events of unknown number and possibly
"endless" pauses in between. The typical scenario here is a stock ticker,
which sends price updates at some random time. Possibly one event per
second. Possibly one per year. We simply can't anticipate, so how to code
it? A visualization of this ticker sends a request to initialize a
"session", and will then listen for events. We all know this as "event loop
pattern": Receive event, process event, wait. With reactive programming, we
can concentrate on writing the "process event" part only, while "receive
event" and "wait" parts of that loop (and the loop itself) are hidden. Pure
IoC. An underlying programming framework (JAX-RS Client) will do that hidden
part, serving as an IoC container, and that Client framework is free to
decide about the way to do that, possibly (and hopefully) using non-blocking
APIs, work-stealing, thread pooling, and all the other smart things that
keeps the GUI reactive, and reduces CPU load by preventing unnecessary
blocking, spinning, etc.

REST is an event-driven paradigm, and JAX-RS already supports this in a
declarative way already. But, just like servlets narrows "event" down to
"http request", JAX-RS narrows "event" down to "http method", which is not
application-level events (like "stock price received"). Looking at
asynchronous processing and the hype around complex event processing, it
might make sense to use reactive programming on the server side to step up
to the application-level and event combinations. For example, our server
might listen to two event sources ("stock price change" and "order
submittance / order cancellation") and needs to "broadcast" when a
particular event combination happens (like "share price higher than highest
valid bid", where server A publishes events on share price changes, while
server B publishes events about changes in the order book). To solve this,
our server needs to keep some "history" of both event sources. This can be
done rather simple with local properties updated by the two event sources,
and binding that properties to provide a third property using an operation
(here: when-higher-than-max), the result. When that result changes, our
server broadcasts an event to any waiting asynchronous clients. A reactive
API would solve this is three lines of code, solely by defining the two
source properties and what they wait for (received SSE), and the resulting
third property and what to do when it changes (send SSE).

These might not be the best examples, but it showcases the need and
usefulness of reactive programming in a JAX-RS application in client AND
server.

The question now is: Do we NEED that? And if we need that, shall we define
our own, NEW, API or reuse an existing one?

In anticipation I'd like to provide my personal statement: Yes to need, yes
to reuse. Event processing (i. e. produce events as combination of other
events) is very useful in many applications. There already is a reactive API
bundled with Oracle's Java SE distribution, hence available on virtually
most JREs (Oracle's, not IBM's). It is part of the JavaFX open source
product, and found in a mostly standalone package. Rather every JavaFX user
is mastering it already. Hence, I do not see a need for a complete new API,
but think it might make more sense to use that one as a starting point:
JavaFX Beans Binding API. It allows to define properties which can be bound
to other properties (or simply spoken, to event sources), which can be bound
in turn to operations (simply spoken, to operations), forming an
event-driven process chain. It works well, is simple, well documented,
scalable, and performance-optimized. But it is completely non-declarative,
i. e. it does not build on annotations but on algorithmic coding (there is
no need for annotations in JavaFX, as JavaFX uses the declarative FXML
language to define the chains, hence algorithmic programming is optional).
As there is no FXML in JAX-RS (and I assume nobody wants to have that) there
might arise a need to at least define annotations to declare the chains in
lieu FXML and to reduce the need for algorithmic coding.

I did not make up my mind to a point beyond that and like to pass on to Bill
and Sergey here, as Marek and Santiago where already informed about my
proposal already. :-)

Regards
-Markus