Design: Convention, Status: Accepted
Operations on the asynchronous clients return CompleteableFuture<T>
where T
is the response type for the operation. This is somewhat curious in that CompleteableFuture
is a concrete implementation rather than an interface. The alternative to returning a CompleteableFuture
would be to return a CompletionStage
, an interface intended to allow chaining of asynchronous operations.
The key advantage of CompleteableFuture
is that it implements both the CompletionStage
and Future
interfaces - giving users of the SDK maximum flexibility when it comes to handling responses from their asynchronous calls.
Currently CompleteableFuture
is the only implementation of CompletionStage
that ships with the JDK. Whilst it's possible that future implementations will be added CompletionStage
will always be tied to CompleteableFuture
via the #toCompletableFuture
method. Additionally, CompleteableFuture
is not a final
class and thus could be extended if there was a requirement to do so.
One of the perceived risks with exposing CompleteableFuture
rather than CompletionStage
is that a user of the SDK may spuriously call #complete
or #completeExceptionally
which could cause unintended consequences in their application and the SDK itself. However this risk is also present on the CompletionStage
via the #toCompletableFuture
method.
If the CompletionStage
interface did not have a #toCompletableFuture
method the argument for using it would be a lot stronger, however as it stands the interface and its implementation are tightly coupled.
Using CompleteableFuture
gives users the best bang for their buck without much additional risk.