# The Java EE 7 Tutorial

# 30.1 Overview of the Client API

The JAX-RS Client API provides a high-level API for accessing any REST resources, not just JAX-RS services. The Client API is defined in the `javax.ws.rs.client` package.

## 30.1.1 Creating a Basic Client Request Using the Client API

The following steps are needed to access a REST resource using the Client API.

1. Obtain an instance of the `javax.ws.rs.client.Client` interface.

2. Configure the `Client` instance with a target.

3. Create a request based on the target.

4. Invoke the request.

The Client API is designed to be fluent, with method invocations chained together to configure and submit a request to a REST resource in only a few lines of code.

    Client client = ClientBuilder.newClient();
    String name = client.target("http://example.com/webapi/hello")
            .request(MediaType.TEXT_PLAIN)
            .get(String.class);

In this example, the client instance is first created by calling the `javax.ws.rs.client.ClientBuilder.newClient` method. Then, the request is configured and invoked by chaining method calls together in one line of code. The `Client.target` method sets the target based on a URI. The `javax.ws.rs.client.WebTarget.request` method sets the media type for the returned entity. The `javax.ws.rs.client.Invocation.Builder.get` method invokes the service using an HTTP `GET` request, setting the type of the returned entity to `String`.

### 30.1.1.1 Obtaining the Client Instance

The `Client` interface defines the actions and infrastructure a REST client requires to consume a RESTful web service. Instances of `Client` are obtained by calling the `ClientBuilder.newClient` method.

    Client client = ClientBuilder.newClient();

Use the `close` method to close `Client` instances after all the invocations for the target resource have been performed:

    Client client = ClientBuilder.newClient();
    ...
    client.close();

`Client` instances are heavyweight objects. For performance reasons, limit the number of `Client` instances in your application, as the initialization and destruction of these instances may be expensive in your runtime environment.

### 30.1.1.2 Setting the Client Target

The target of a client, the REST resource at a particular URI, is represented by an instance of the `javax.ws.rs.client.WebTarget` interface. You obtain a `WebTarget` instance by calling the `Client.target` method and passing in the URI of the target REST resource.

    Client client = ClientBuilder.newClient();
    WebTarget myResource = client.target("http://example.com/webapi");

For complex REST resources, it may be beneficial to create several instances of `WebTarget`. In the following example, a base target is used to construct several other targets that represent different services provided by a REST resource.

    Client client = ClientBuilder.newClient();
    WebTarget base = client.target("http://example.com/webapi");
    // WebTarget at http://example.com/webapi/read
    WebTarget read = base.path("read");
    // WebTarget at http://example.com/webapi/write
    WebTarget write = base.path("write");

The `WebTarget.path` method creates a new `WebTarget` instance by appending the current target URI with the path that was passed in.

### 30.1.1.3 Setting Path Parameters in Targets

Path parameters in client requests can be specified as URI template parameters, similar to the template parameters used when defining a resource URI in a JAX-RS service. Template parameters are specified by surrounding the template variable with braces (`{}`). Call the `resolveTemplate` method to substitute the `{username}`, and then call the `queryParam` method to add another variable to pass.

    WebTarget myResource = client.target("http://example.com/webapi/read")
            .path("{userName}")
            .resolveTemplate("userName", "janedoe")        .queryParam("chapter", "1");// http://example.com/webapi/read/janedoe?chapter=1Response response = myResource.request(...)        .get();

### 30.1.1.4 Invoking the Request

After setting and applying any configuration options to the target, call one of the `WebTarget.request` methods to begin creating the request. This is usually accomplished by passing to `WebTarget.request` the accepted media response type for the request either as a string of the MIME type or using one of the constants in `javax.ws.rs.core.MediaType`. The `WebTarget.request` method returns an instance of `javax.ws.rs.client.Invocation.Builder`, a helper object that provides methods for preparing the client request.

    Client client = ClientBuilder.newClient();
    WebTarget myResource = client.target("http://example.com/webapi/read");
    Invocation.Builder builder = myResource.request(MediaType.TEXT_PLAIN);

Using a `MediaType` constant is equivalent to using the string defining the MIME type.

    Invocation.Builder builder = myResource.request("text/plain");

After setting the media type, invoke the request by calling one of the methods of the `Invocation.Builder` instance that corresponds to the type of HTTP request the target REST resource expects. These methods are:

- `get()`

- `post()`

- `delete()`

- `put()`

- `head()`

- `options()`

For example, if the target REST resource is for an HTTP GET request, call the `Invocation.Builder.get` method. The return type should correspond to the entity returned by the target REST resource.

    Client client = ClientBuilder.newClient();
    WebTarget myResource = client.target("http://example.com/webapi/read");
    String response = myResource.request(MediaType.TEXT_PLAIN)
            .get(String.class);

If the target REST resource is expecting an HTTP POST request, call the `Invocation.Builder.post` method.

    Client client = ClientBuilder.newClient();
    StoreOrder order = new StoreOrder(...);
    WebTarget myResource = client.target("http://example.com/webapi/write");
    TrackingNumber trackingNumber = myResource.request(MediaType.APPLICATION_XML)
                                       .post(Entity.xml(order), TrackingNumber.class);

In the preceding example, the return type is a custom class and is retrieved by setting the type in the `Invocation.Builder.post(Entity<?> entity, Class<T> responseType)` method as a parameter.

If the return type is a collection, use `javax.ws.rs.core.GenericType<T>` as the response type parameter, where `T` is the collection type:

    List<StoreOrder> orders = client.target("http://example.com/webapi/read")
            .path("allOrders")
            .request(MediaType.APPLICATION_XML)
            .get(new GenericType<List<StoreOrder>>() {});

This preceding example shows how methods are chained together in the Client API to simplify how requests are configured and invoked.