Module elastic::client [] [src]

HTTP client, requests and responses.

This module contains the HTTP client, as well as request and response types.

The gist

elastic provides two clients:

Building a synchronous client

Use a SyncClientBuilder to configure a synchronous client.

let client = SyncClientBuilder::new().build()?;

Requests on the synchronous client will block the current thread until a response is received. The response is returned as a Result.

Building an asynchronous client

Use an AsyncClientBuilder to configure an asynchronous client.

The asynchronous client requires a handle to a tokio::reactor::Core:

let client = AsyncClientBuilder::new().build(&core.handle())?;

Requests on the asynchronous client won't block the current thread. Instead a Future will be returned immediately that will resolve to a response at a later point.

Sending requests

Requests can be sent with an instance of a client using a builder API:

let response = client.search::<Value>()
                     .index("myindex")
                     .ty(Some("myty"))
                     .body(json!({
                         "query": {
                             "query_string": {
                                 "query": "*"
                             }
                         }
                     }))
                     .send();

match response {
    Ok(response) => {
        // Iterate through the response hits
        for hit in response.hits() {
            println!("{:?}", hit);
        }
    },
    Err(Error::Api(e)) => {
        // handle a REST API error
    },
    Err(e) => {
        // handle a HTTP or JSON error
    }
}

SyncClient and AsyncClient offer the same request methods. The details are explained below.

Request builders

Some commonly used endpoints have high-level builder methods you can use to configure requests easily. They're exposed as methods on the Client:

Client method Elasticsearch API Raw request type Response type
search Search SearchRequest SearchResponse
document_get Get Document GetRequest GetResponse
document_index Index Document IndexRequest IndexResponse
document_update Update Document UpdateRequest UpdateResponse
document_delete Delete Document DeleteRequest DeleteResponse
document_put_mapping Put Mapping IndicesPutMappingRequest CommandResponse
index_create Create Index IndicesCreateRequest CommandResponse
index_open Open Index IndicesOpenRequest CommandResponse
index_close Close Index IndicesCloseRequest CommandResponse
index_delete Delete Index IndicesDeleteRequest CommandResponse
index_exists Index Exists IndicesExistsRequest IndicesExistsResponse
ping - PingRequest PingResponse

All builders follow a standard pattern:

  • The Client method takes all required parameters without type inference
  • Optional or inferred parameters can be overridden in builder methods with type inference
  • send will return a specific response type

The high-level request builders are wrappers around the Client.request method, taking a raw request type. For example, a document_get request for a value:

let response = client.document_get::<Value>(index("values"), id(1)).send()?;

is equivalent to:

let response = client.request(GetRequest::for_index_ty_id("values", "value", 1))
                     .send()?
                     .into_response::<GetResponse<Value>>()?;

Raw request types

Not all endpoints have strongly-typed builders, but all Elasticsearch API endpoints have a specific raw request type that can be used to build a request manually and send with the Client.request method. The builders described above are just wrappers around these request types, but that doesn't mean raw requests are a second-class API. You have more control over how requests are serialised, sent and deserialised using the raw requests API. All request endpoints live in the endpoints module.

The process of sending raw requests is described in more detail below.

The raw request process

The pieces involved in sending an Elasticsearch API request and parsing the response are modular. Each one exposes Rust traits you can implement to support your own logic but if you just want to send a search/get request and parse a search/get response then you won't need to worry about this so much.

The basic flow from request to response is:

1) Turn a concrete request type into a RawRequestBuilder:

[RequestType] ---> [Client.request()] ---> [RawRequestBuilder]

2) Send the RawRequestBuilder and get a response builder:

[RawRequestBuilder.send()] ---> [ResponseBuilder]

3) Parse the response builder to a response type:

[ResponseBuilder.into_response()] ---> [ResponseType]

The example below shows how these pieces fit together in code by sending a simple synchronous SearchRequest, with the steps in the above process labelled:

let req = SearchRequest::for_index("_all", empty_body());

let response = client.request(req) // 1
                     .send()? // 2
                     .into_response::<SearchResponse<Value>>()?; // 3

1. Building raw requests

The endpoints module contains code-generated request types for the Elasticsearch REST API. Each request type expects its parameters upfront and is generic over the request body.

A raw search request:

let req = {
    let body = json!({
        "query": {
            "query_string": {
                "query": "*"
            }
        }
    });

    SearchRequest::for_index_ty("myindex", "myty", body)
};

A raw request to index a document:

let req = {
    let body = serde_json::to_string(&doc)?;

    IndexRequest::for_index_ty_id("myindex", "myty", 1, body)
};

2. Sending requests

Both high-level request builders and raw requests have some common builder methods:

  • params for setting url query parameters
  • a send method for sending the request. For high-level requests this returns a strongly-typed response. For raw requests this returns a response builder. If the request was sent synchronously, the response is returned as a Result. If the request was sent asynchronously, the response is returned as a Future.
let request_builder = client.request(req);

// Set additional url parameters
let request_builder = request_builder.params(|p| p
    .url_param("pretty", true)
    .url_param("refresh", true)
);

// Send the request
let response = request_builder.send();

3. Parsing responses synchronously

Call SyncResponseBuilder.into_response on a sent request to get a strongly typed response:

let response = client.request(req)
                     .send()?
                     .into_response::<SearchResponse<Value>>();

match response {
    Ok(response) => {
        // Iterate through the response hits
        for hit in response.hits() {
            println!("{:?}", hit);
        }
    },
    Err(Error::Api(e)) => {
        // handle a REST API error
    },
    Err(e) => {
        // handle a HTTP or JSON error
    }
}

Alternatively, call SyncResponseBuilder.into_raw on a sent request to get a raw SyncHttpResponse:

let mut response = client.request(req)
                         .send()?
                         .into_raw();

let mut body = String::new();
response.read_to_string(&mut body)?;

println!("{}", body);

SyncHttpResponse implements the standard Read trait so you can buffer out the raw response data. For more details see the responses module.

3. Parsing responses asynchronously

Call AsyncResponseBuilder.into_response on a sent request to get a strongly typed response:

let future = client.request(req)
                   .send()
                   .and_then(|response| response.into_response::<SearchResponse<Value>>());

future.and_then(|response| {
    // Iterate through the response hits
    for hit in response.hits() {
        println!("{:?}", hit);
    }

    Ok(())
});

Alternatively, call AsyncResponseBuilder.into_raw on a sent request to get a raw AsyncHttpResponse:

let future = client.request(req)
                   .send()
                   .and_then(|response| Ok(response.into_raw()))
                   .and_then(|raw| raw.concat2())
                   .map_err(|e| Box::new(e) as Box<::std::error::Error>);

future.and_then(|body| {
    let body = str::from_utf8(body.as_ref())?;

    println!("{}", body);

    Ok(())
});

AsyncHttpResponse implements the async Stream trait so you can buffer out the raw response data. For more details see the responses module.

Modules

prelude

A glob import for convenience.

requests

Request types for the Elasticsearch REST API.

responses

Response types for the Elasticsearch REST API.

Structs

AsyncClientBuilder

A builder for an asynchronous client.

AsyncSender

An asynchronous request sender.

Client

A HTTP client for the Elasticsearch REST API.

Pending

A future returned by calling send.

RequestParams

Misc parameters for any request.

SyncClientBuilder

A builder for a syncronous client.

SyncSender

A synchronous request sender.

Traits

IntoAsyncHttpClient

A type that can be used to construct an async http client.

Sender

Represents a type that can send a request.

Type Definitions

AsyncClient

An asynchronous Elasticsearch client.

SyncClient

A synchronous Elasticsearch client.