Blocking and asynchronous clientsedit

API clients come in two flavors: blocking and asynchronous. All methods on asynchronous clients return a standard CompletableFuture.

Both flavors can be used at the same time depending on your needs, sharing the same transport object:

ElasticsearchTransport transport = ...

// Synchronous blocking client
ElasticsearchClient client = new ElasticsearchClient(transport);

if (client.exists(b -> b.index("products").id("foo")).value()) {"product exists");

// Asynchronous non-blocking client
ElasticsearchAsyncClient asyncClient =
    new ElasticsearchAsyncClient(transport);

    .exists(b -> b.index("products").id("foo"))
    .whenComplete((response, exception) -> {
        if (exception != null) {
            logger.error("Failed to index", exception);
        } else {
  "Product exists");

Although we won’t go in deeper details on asynchronous programming in Java, remember to handle failures of asynchronous tasks. It’s easy to overlook them and have errors go unnoticed.

The source code for the examples above can be found in the Java API Client tests.