﻿---
title: Performing requests with the Elasticsearch Java REST 5 client
description: Once the RestClient has been created, requests can be sent by calling either performRequest or performRequestAsync. performRequest is synchronous and...
url: https://www.elastic.co/elastic/docs-builder/docs/3028/reference/elasticsearch/clients/java/transport/rest5-client/usage/requests
products:
  - Elasticsearch Client
  - Elasticsearch Java Client
---

# Performing requests with the Elasticsearch Java REST 5 client
Once the `RestClient` has been created, requests can be sent by calling either `performRequest` or `performRequestAsync`. `performRequest` is synchronous and will block the calling thread and return the `Response` when the request is successful or throw an exception if it fails. `performRequestAsync` is asynchronous and accepts a `ResponseListener` argument that it calls with a `Response` when the request is successful or with an `Exception` if it fails.
This is synchronous:
```java
Request request = new Request(
    "GET", 
    "/");  

Response response = restClient.performRequest(request);
```

And this is asynchronous:
```java
Request request = new Request(
    "GET", 
    "/");  

Cancellable cancellable = restClient.performRequestAsync(
    request,
    new ResponseListener() {
        @Override
        public void onSuccess(Response response) {
           
        }

        @Override
        public void onFailure(Exception exception) {
           
        }
    });
```

You can add request parameters to the request object:
```java
request.addParameter("pretty", "true");
```

You can set the body of the request to any `HttpEntity`:
```java
request.setEntity(new StringEntity(
    "{\"json\":\"text\"}",
    ContentType.APPLICATION_JSON));
```

<important>
  The `ContentType` specified for the `HttpEntity` is important because it will be used to set the `Content-Type` header so that Elasticsearch can properly parse the content.
</important>

You can also set it to a `String` which will default to a `ContentType` of `application/json`.
```java
request.setJsonEntity("{\"json\":\"text\"}");
```


## RequestOptions

The `RequestOptions` class holds parts of the request that should be shared between many requests in the same application. You can make a singleton instance and share it between all requests:
```java
private static final RequestOptions COMMON_OPTIONS;

static {
    RequestOptions.Builder builder = RequestOptions.DEFAULT
        .toBuilder()
        .addHeader("Authorization", "Bearer " + TOKEN)
        .setHttpAsyncResponseConsumerFactory(          
            HttpAsyncResponseConsumerFactory.DEFAULT
        );

    COMMON_OPTIONS = builder.build();
}
```

`addHeader` is for headers that are required for authorization or to work with a proxy in front of Elasticsearch. There is no need to set the `Content-Type` header because the client will automatically set that from the `HttpEntity` attached to the request.
You can set the `NodeSelector` which controls which nodes will receive requests. `NodeSelector.SKIP_DEDICATED_MASTERS` is a good choice.
You can also customize the response consumer used to buffer the asynchronous responses. The default consumer will buffer up to 100MB of response on the JVM heap. If the response is larger then the request will fail. You could, for example, lower the maximum size which might be useful if you are running in a heap constrained environment like the example above.
Once you’ve created the singleton you can use it when making requests:
```java
request.setOptions(COMMON_OPTIONS);
```

You can also customize these options on a per request basis. For example, this adds an extra header:
```java
RequestOptions.Builder options = COMMON_OPTIONS.toBuilder();
options.addHeader("cats", "knock things off of other things");
request.setOptions(options);
```


## Multiple parallel asynchronous actions

The client is quite happy to execute many actions in parallel. The following example indexes many documents in parallel. In a real world scenario you’d probably want to use the `_bulk` API instead, but the example is illustrative.
```java
final CountDownLatch latch = new CountDownLatch(documents.length);
for (int i = 0; i < documents.length; i++) {
    Request request = new Request("PUT", "/posts/doc/" + i);
    //let's assume that the documents are stored in an HttpEntity array
    request.setEntity(documents[i]);
    restClient.performRequestAsync(
        request,
        new ResponseListener() {
            @Override
            public void onSuccess(Response response) {
               
                latch.countDown();
            }

            @Override
            public void onFailure(Exception exception) {
               
                latch.countDown();
            }
        }
    );
}
latch.await();
```


## Cancelling asynchronous requests

The `performRequestAsync` method returns a `Cancellable` that exposes a single public method called `cancel`. Such method can be called to cancel the on-going request. Cancelling a request will result in aborting the http request through the underlying http client. On the server side, this does not automatically translate to the execution of that request being cancelled, which needs to be specifically implemented in the API itself.
The use of the `Cancellable` instance is optional and you can safely ignore this if you don’t need it. A typical usecase for this would be using this together with frameworks like Rx Java or the Kotlin’s `suspendCancellableCoRoutine`. Cancelling no longer needed requests is a good way to avoid putting unnecessary load on Elasticsearch.
```java
Request request = new Request("GET", "/posts/_search");
Cancellable cancellable = restClient.performRequestAsync(
    request,
    new ResponseListener() {
        @Override
        public void onSuccess(Response response) {
           
        }

        @Override
        public void onFailure(Exception exception) {
           
        }
    }
);
cancellable.cancel();
```