# RESTEasy Client API

## JAX-RS 2.0 Client API

JAX-RS 2.0 introduces a new client API so that you can make http requests to your remote RESTful web services. It is a 'fluent' request building API with really 3 main classes: Client, WebTarget, and Response. The Client interface is a builder of WebTarget instances. WebTarget represents a distinct URL or URL template from which you can build more sub-resource WebTargets or invoke requests on.

There are really two ways to create a Client. Standard way, or you can use the ResteasyClientBuilder class. The advantage of the latter is that it gives you a few more helper methods to configure your client.

                Client client = ClientBuilder.newClient();
                ... or...
                Client client = ClientBuilder.newBuilder().build();
                WebTarget target = client.target("http://foo.com/resource");
                Response response = target.request().get();
                String value = response.readEntity(String.class);
                response.close();  // You should close connections!

                ResteasyClient client = new ResteasyClientBuilder().build();
                ResteasyWebTarget target = client.target("http://foo.com/resource");

RESTEasy will automatically load a set of default providers. (Basically all classes listed in all META-INF/services/javax.ws.rs.ext.Providers files). Additionally, you can manually register other providers, filters, and interceptors through the Configuration object provided by the method call Client.configuration(). Configuration also lets you set various configuration properties that may be needed.

Each WebTarget has its own Configuration instance which inherits the components and properties registered with its parent. This allows you to set specific configuration options per target resource. For example, username and password.

One RESTEasy extension to the client API is the ability to specify that requests should be sent in "chunked" transfer mode. There are two ways of doing that. One is to configure an `org.jboss.resteasy.client.jaxrs.ResteasyWebTarget` so that all requests to that target are sent in chunked mode:

          ResteasyClient client = new ResteasyClientBuilder().build();
          ResteasyWebTarget target = client.target("http://localhost:8081/test");
          target.setChunked(b.booleanValue());
          Invocation.Builder request = target.request();

Alternatively, it is possible to configure a particular request to be sent in chunked mode:

          ResteasyClient client = new ResteasyClientBuilder().build();
          ResteasyWebTarget target = client.target("http://localhost:8081/test");
          ClientInvocationBuilder request = (ClientInvocationBuilder) target.request();
          request.setChunked(b);

Note that `org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder`, unlike `javax.ws.rs.client.Invocation.Builder`, is a RESTEasy class.

Note. The ability to send in chunked mode depends on the underlying transport layer; in particular, it depends on which implementation of `org.jboss.resteasy.client.jaxrs.ClientHttpEngine` is being used. Currently, only the default implementation, `ApacheHttpClient43Engine` and the older `ApacheHttpClient4Engine`, both in package `org.jboss.resteasy.client.jaxrs.engines`, support chunked mode. See Section Apache HTTP Client 4.x and other backends for more information.

## RESTEasy Proxy Framework

The RESTEasy Proxy Framework is the mirror opposite of the JAX-RS server-side specification. Instead of using JAX-RS annotations to map an incoming request to your RESTFul Web Service method, the client framework builds an HTTP request that it uses to invoke on a remote RESTful Web Service. This remote service does not have to be a JAX-RS service and can be any web resource that accepts HTTP requests.

RESTEasy has a client proxy framework that allows you to use JAX-RS annotations to invoke on a remote HTTP resource. The way it works is that you write a Java interface and use JAX-RS annotations on methods and the interface. For example:

    public interface SimpleClient
    {
       @GET
       @Path("basic")
       @Produces("text/plain")
       String getBasic();

       @PUT
       @Path("basic")
       @Consumes("text/plain")
       void putBasic(String body);

       @GET
       @Path("queryParam")
       @Produces("text/plain")
       String getQueryParam(@QueryParam("param")String param);

       @GET
       @Path("matrixParam")
       @Produces("text/plain")
       String getMatrixParam(@MatrixParam("param")String param);

       @GET
       @Path("uriParam/{param}")
       @Produces("text/plain")
       int getUriParam(@PathParam("param")int param);
    }

RESTEasy has a simple API based on Apache HttpClient. You generate a proxy then you can invoke methods on the proxy. The invoked method gets translated to an HTTP request based on how you annotated the method and posted to the server. Here's how you would set this up:

                Client client = ClientBuilder.newClient();
                WebTarget target = client.target("http://example.com/base/uri");
                ResteasyWebTarget rtarget = (ResteasyWebTarget)target;

                SimpleClient simple = rtarget.proxy(SimpleClient.class);
                client.putBasic("hello world");

Alternatively you can use the RESTEasy client extension interfaces directly:

                ResteasyClient client = new ResteasyClientBuilder().build();
                ResteasyWebTarget target = client.target("http://example.com/base/uri");

                SimpleClient simple = target.proxy(SimpleClient.class);
                client.putBasic("hello world");

@CookieParam works the mirror opposite of its server-side counterpart and creates a cookie header to send to the server. You do not need to use @CookieParam if you allocate your own javax.ws.rs.core.Cookie object and pass it as a parameter to a client proxy method. The client framework understands that you are passing a cookie to the server so no extra metadata is needed.

The framework also supports the JAX-RS locator pattern, but on the client side. So, if you have a method annotated only with @Path, that proxy method will return a new proxy of the interface returned by that method.

### Abstract Responses

Sometimes you are interested not only in the response body of a client request, but also either the response code and/or response headers. The Client-Proxy framework has two ways to get at this information

You may return a javax.ws.rs.core.Response.Status enumeration from your method calls:

    @Path("/")
    public interface MyProxy {
       @POST
       Response.Status updateSite(MyPojo pojo);
    }

Internally, after invoking on the server, the client proxy internals will convert the HTTP response code into a Response.Status enum.

If you are interested in everything, you can get it with the javax.ws.rs.core.Response class:

    @Path("/")
    public interface LibraryService {

       @GET
       @Produces("application/xml")
       Response getAllBooks();
    }

### Response proxies

A further extension implemented by the RESTEasy client proxy framework is the "response proxy facility", where a client proxy method returns an interface that represents the information contained in a `javax.ws.rs.core.Response`. Such an interface must be annotated with `@ResponseObject` from package `org.jboss.resteasy.annotations`, and its methods may be further annotated with `@Body`, `@LinkHeaderParam`, and `@Status` from the same package, as well as `javax.ws.rs.HeaderParam`. Consider the following example.

       @ResponseObject
       public interface TestResponseObject {

          @Status
          int status();

          @Body
          String body();

          @HeaderParam("Content-Type")
          String contentType();

          ClientResponse response();
       }

       @Path("test")
       public interface TestClient {

          @GET
          TestResponseObject get();
       }

       @Path("test")
       public static class TestResource {

          @GET
          @Produces("text/plain")
          public String get() {
             return "ABC";
          }
       }

Here, `TestClient` will define the client side proxy for `TestResource`. Note that `TestResource.get()` returns a `String` but the proxy based on `TestClient` will return a `TestResponseObject` on a call to `get()`:

          Client client = ClientBuilder.newClient();
          TestClient ClientInterface = ProxyBuilder.builder(TestClient.class, client.target("http://localhost:8081")).build();
          TestResponseObject tro = ClientInterface.get();

The methods of `TestResponseObject` provide access to various pieces of information about the response received from `TestResponse.get()`. This is where the annotations on those methods come into play. `status()` is annotated with `@Status`, and a call to `status()` returns the HTTP status. Similarly, `body()` returns the returned entity, and `contentType()` returns the value of the response header Content-Type:

          System.out.println("status: " + tro.status());
          System.out.println("entity: " + tro.body());
          System.out.println("Content-Type: " + tro.contentType());

will yield

    status: 200
    entity: ABC
    Content-Type: text/plain;charset=UTF-8

Note that there is one other method in `TestResponseObject`, `response()`, that has no annotation. When RESTEasy sees a method in an interface annotated with `@ResponseObject` that returns a `javax.ws.rs.core.Response` (or a subclass thereof), it will return a `org.jboss.resteasy.client.jaxrs.internal.ClientResponse`. For example,

          ClientResponse clientResponse =  tro.response();
          System.out.println("Content-Length: " + clientResponse.getLength());

Perhaps the most interesting piece of the response proxy facility is the treatment of methods annotated with `@LinkHeaderParam`. Its simplest use is to assist in accessing a `javax.ws.rs.core.Link` returned by a resource method. For example, let's add

          @GET
          @Path("/link-header")
          public Response getWithHeader(@Context UriInfo uri) {
             URI subUri = uri.getAbsolutePathBuilder().path("next-link").build();
             Link link = new LinkBuilderImpl().uri(subUri).rel("nextLink").build();
             return Response.noContent().header("Link", link.toString()).build();
          }

to `TestResource`, add

           @GET
           @Path("link-header")
           ResponseObjectInterface performGetBasedOnHeader();

to `ClientInterface`, and add

           @LinkHeaderParam(rel = "nextLink")
           URI nextLink();

to `ResponseObjectInterface`. Then calling

          ResponseObjectInterface obj = ClientInterface.performGetBasedOnHeader();
          System.out.println("nextLink(): " + obj.nextLink());

will access the `LinkHeader` returned by `TestResource.getWithHeader()`:

    nextlink: http://localhost:8081/test/link-header/next-link

Last but not least, let's add

          @GET
          @Produces("text/plain")
          @Path("/link-header/next-link")
          public String getHeaderForward() {
             return "forwarded";
          }

to `TestResource` and

           @GET
           @LinkHeaderParam(rel = "nextLink")
           String followNextLink();

to `ResponseObjectInterface`. Note that, unlike `ResponseObjectInterface.nextLink()`, `followNextLink()` is annotated with `@GET`; that is, it qualifies as (the client proxy to) a resource method. When executing `followNextLink()`, RESTEasy will retrieve the value of the `Link` returned by `TestResource.getWithHeader()` and then will make a GET invocation on the `URL` in that `Link`. Calling

          System.out.println("followNextLink(): " + obj.followNextLink());

causes RESTEasy to retrieve the `URL` http://localhost:8081/test/link-header/next-link from the call to `TestResource.getWithHeader()` and then perform a GET on it, invoking `TestResource.getHeaderForward()`:

    followNextLink(): forwarded

Note. This facility for extracting a `URL` and following it is a step toward supporting the Representation State Transfer principle of HATEOAS. For more information, see RESTful Java with JAX-RS 2.0, 2nd Edition by Bill Burke.

### Giving client proxy an ad hoc URI

Client proxies figure out appropriate URIs for targeting resource methods by looking at `@Path` annotations in the client side interface, but it is also possible to pass URIs explicitly to the proxy through the use of the `org.jboss.resteasy.annotations.ClientURI` annotation. For example, let `TestResource` be a client side interface and `TestResourceImpl` a server resource:

       @Path("")
       public interface TestResource {

          @GET
          @Path("dispatch")
          public String dispatch(@ClientURI String uri);
       }

       @Path("")
       public static class TestResourceImpl {

          @GET
          @Path("a")
          public String a() {
             return "a";
          }

          @GET
          @Path("b")
          public String b() {
             return "b";
          }
       }

Calling `TestResource.dispatch()` allows specifying a specific URI for accessing a resource method. In the following, let BASE_URL be the address of the `TestResourceImpl` resource.

       private static String BASE_URL = "http://localhost:8081/";
       ...
       public void test() throws Exception
       {
          ResteasyClient client = new ResteasyClientBuilder().build();
          TestResource proxy = client.target(BASE_URL).proxy(TestResource.class);
          String name = proxy.dispatch(BASE_URL + "a");
          System.out.println("name: " + name);
          name = proxy.dispatch(BASE_URL + "b");
          System.out.println("name: " + name);
          client.close();
       }

Then passing "http://localhost:8081/a" and "http://localhost/b" to `dispatch()` invokes `TestResourceImp.a()` and `TestResourceImpl.b()` respectively, yielding the output

    name: a
    name: b

### Sharing an interface between client and server

It is generally possible to share an interface between the client and server. In this scenario, you just have your JAX-RS services implement an annotated interface and then reuse that same interface to create client proxies to invoke on the client-side.

## Apache HTTP Client 4.x and other backends

Network communication between the client and server is handled by default in RESTEasy. The interface between the RESTEasy Client Framework and the network is defined by RESTEasy's `ClientHttpEngine` interface. RESTEasy ships with multiple implementations of this interface.

The default implementation is `ApacheHttpClient43Engine`, which uses version 4.3 of the `HttpClient` from the Apache `HttpComponents` project. `ApacheHttpClient4Engine` is an implementation that uses the pre-Apache 4.3 version, to provide backward compatibility. RESTEasy automatically selects one of these two `ClientHttpEngine` implementations based upon the detection of the Apache version.

`ApacheHttpAsyncClient4Engine`, instead, is built on top of HttpAsyncClient (still from the Apache HttpComponents project) with internally dispatches requests using a non-blocking IO model.

`JettyClientEngine` is built on top of Eclipse Jetty HTTP engine, which is possibly an interesting option for those already running on the Jetty server.

Finally, `InMemoryClientEngine` is an implementation that dispatches requests to a server in the same JVM and `URLConnectionEngine` is an implementation that uses `java.net.HttpURLConnection`.

RESTEasy ClientHttpEngine implementations |
ApacheHttpClient43Engine | Uses HttpComponents HttpClient 4.3 api
ApacheHttpClient4Engine | Uses HttpComponents HttpClient pre-4.3 api
ApacheHttpAsyncClient4Engine | Uses HttpComponents HttpAsyncClient
JettyClientEngine | Uses Eclipse Jetty
InMemoryClientEngine | Dispatches requests to a server in the same JVM
URLConnectionEngine | Uses java.net.HttpURLConnection

The RESTEasy Client Framework can also be customized. The user can provide their own implementations of `ClientHttpEngine` to the `ResteasyClient`.

    ClientHttpEngine myEngine = new ClientHttpEngine() {
        protected SSLContext sslContext;
        protected HostnameVerifier hostnameVerifier;

        @Override
        public ClientResponse invoke(ClientInvocation request) {
            // implement your processing code and return a
            // org.jboss.resteasy.client.jaxrs.internal.ClientResponse
            // object.
        }

        @Override
        public SSLContext getSslContext() {
           return sslContext;
        }

        @Override
        public HostnameVerifier getHostnameVerifier() {
           return hostnameVerifier;
        }

        @Override
        public void close() {
           // do nothing
        }
    };

    ResteasyClient client = new RESTEasyClientBuilder().httpEngine(myEngine).build();

RESTEasy and `HttpClient` make reasonable default decisions so that it is possible to use the client framework without ever referencing `HttpClient`. For some applications it may be necessary to drill down into the `HttpClient` details. `ApacheHttpClient43Engine` and `ApacheHttpClient4Engine` can be supplied with an instance of `org.apache.http.client.HttpClient` and an instance of `org.apache.http.protocol.HttpContext`, which can carry additional configuration details into the `HttpClient` layer.

`HttpContextProvider` is a RESTEasy provided interface through which a custom `HttpContext` is supplied to `ApacheHttpClient43Engine` and `ApacheHttpClient4Engine`.

    package org.jboss.resteasy.client.jaxrs.engines;

    import org.apache.http.protocol.HttpContext;

    public interface HttpContextProvider {
       HttpContext getContext();
    }

Here is an example of providing a custom HttpContext

    DefaultHttpClient httpClient = new DefaultHttpClient();
    ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient,
       new HttpContextProvider() {
               @Override
               public HttpContext getContext() {
                  // Configure HttpClient to authenticate preemptively
                  // by prepopulating the authentication data cache.
                  // 1. Create AuthCache instance
                  AuthCache authCache = new BasicAuthCache();
                  // 2. Generate BASIC scheme object and add it to the local auth cache
                  BasicScheme basicAuth = new BasicScheme();
                  authCache.put(getHttpHost(url), basicAuth);
                  // 3. Add AuthCache to the execution context
                  BasicHttpContext localContext = new BasicHttpContext();
                  localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
                  return localContext;
               }
    });

### HTTP redirect

The `ClientHttpEngine` implementations based on Apache `HttpClient` support HTTP redirection. The feaure is disabled by default and has to be enabled by users explicitly:

    ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine();
    engine.setFollowRedirects(true);
    Client client = new ResteasyClientBuilder().httpEngine(engine).build();

### Apache HTTP Client pre-4.3 APIs

The Apache pre-4.3 `HttpClient` implementation uses `org.apache.http.impl.conn.SingleClientConnManager` to manage a single socket and allows `org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager` to replace `SingleClientConnManager` for multithreaded applications. `SingleClientConnManager` manages a single socket at any given time and supports the use case in which one or more invocations are made serially from a single thread.

Here is an example of replacing the `SingleClientConnManager` with `ThreadSafeClientConnManager` in `ApacheHttpClient4Engine`.

    ClientConnectionManager cm = new ThreadSafeClientConnManager();
    HttpClient httpClient = new DefaultHttpClient(cm);
    ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);

For more information about HttpClient (4.x), see the documentation at http://hc.apache.org/httpcomponents-client-ga/tutorial/html/.

Note. It is important to understand the difference between "releasing" a connection and "closing" a connection. Releasing a connection makes it available for reuse. Closing a connection frees its resources and makes it unusable.

`SingleClientConnManager` manages a single socket, which it allocates to at most a single invocation at any given time. Before that socket can be reused, it has to be released from its current use, which can occur in one of two ways. If an execution of a request or a call on a proxy returns a class other than `Response`, then RESTEasy will take care of releasing the connection. For example, in the fragments

    WebTarget target = client.target("http://localhost:8081/customer/123");
    String answer = target.request().get(String.class);

or

    ResteasyWebTarget target = client.target("http://localhost:8081/customer/123");
    RegistryStats stats = target.proxy(RegistryStats.class);
    RegistryData data = stats.get();

RESTEasy will release the connection under the covers. The only counterexample is the case in which the response is an instance of `InputStream`, which must be closed explicitly.

On the other hand, if the result of an invocation is an instance of `Response`, then Response.close() method must be used to released the connection.

    WebTarget target = client.target("http://localhost:8081/customer/123");
    Response response = target.request().get();
    System.out.println(response.getStatus());
    response.close();

You should probably execute this in a try/finally block. Again, releasing a connection only makes it available for another use. It does not normally close the socket.

On the other hand, `ApacheHttpClient4Engine.finalize()` will close any open sockets, but only if it created the `HttpClient` it has been using. If an `HttpClient` has been passed into the `ApacheHttpClient4Executor`, then the user is responsible for closing the connections:

    HttpClient httpClient = new DefaultHttpClient();
    ApacheHttpClient4Engine executor = new ApacheHttpClient4Engine(httpClient);
    ...
    httpClient.getConnectionManager().shutdown();

Note that if `ApacheHttpClient4Engine` has created its own instance of `HttpClient`, it is not necessary to wait for `finalize()` to close open sockets. The `ClientHttpEngine` interface has a `close()` method for this purpose.

Finally, if your javax.ws.rs.client.Client class has created the engine automatically for you, you should call Client.close() and this will clean up any socket connections.

### Apache HTTP Client 4.3 APIs

The Apache 4.3 `HttpClient` implementation uses `org.apache.http.impl.conn.BasicHttpClientConnectionManager` to manage a single socket and `org.apache.http.impl.conn.PoolingHttpClientConnectionManager` to service connection requests from multiple execution threads. RESTEasy's `ClientHttpclientBuilder43` and `ApacheHttpClient43Engine` uses them as well.

### Asynchronous HTTP Request Processing

RESTEasy's default async engine implementation class is ApacheHttpAsyncClient4Engine. It can be set as the active engine by calling method useAsyncHttpEngine in ResteasyClientBuilder.

        Client asyncClient = new ResteasyClientBuilder().useAsyncHttpEngine()
                                 .build();
        Future<Response> future = asyncClient
                                 .target("http://locahost:8080/test").request()
                                 .async().get();
        Response res = future.get();
        Assert.assertEquals(HttpResponseCodes.SC_OK, res.getStatus());
        String entity = res.readEntity(String.class);

#### InvocationCallbacks

InvocationCallbacks are called from within the io-threads and thus must not block or else the application may slow down to a halt. Reading the response is safe because the response is buffered in memory, as are other async and in-memory client-invocations that submit-calls returning a future not containing Response, InputStream or Reader.

       final CountDownLatch latch = new CountDownLatch(1);
       Future<String> future = nioClient.target(generateURL("/test")).request()
             .async().get(new InvocationCallback<String>()
                    {
                       @Override
                       public void completed(String s)
                       {
                          Assert.assertEquals("get", s);
                          latch.countDown();
                          throw new RuntimeException("for the test of it");
                       }

                       @Override
                       public void failed(Throwable error)
                       {
                       }
                    });
       String entity = future.get();
       Assert.assertEquals("get", entity);

InvocationCallbacks may be called seemingly "after" the future-object returns. Thus, responses should be handled solely in the InvocationCallback.

InvocationCallbacks will see the same result as the future-object and vice versa. Thus, if the invocationcallback throws an exception, the future-object will not see it. This is the reason to handle responses only in the InvocationCallback.

#### Async Engine Usage Considerations

Asynchronous IO means non-blocking IO utilizing few threads, typically at most as many threads as number of cores. As such, performance may profit from fewer thread switches and less memory usage due to fewer thread-stacks. But doing synchronous, blocking IO (the invoke-methods not returning a future) may suffer, because the data has to be transferred piecewise to/from the io-threads.

Request-Entities are fully buffered in memory, thus HttpAsyncClient is unsuitable for very large uploads. Response-Entities are buffered in memory, except if requesting a Response, InputStream or Reader as Result. Thus for large downloads or COMET, one of these three return types must be requested, but there may be a performance penalty because the response-body is transferred piecewise from the io-threads. When using InvocationCallbacks, the response is always fully buffered in memory.

### Jetty Client Engine

As a drop in replacement, RESTEasy allows selecting a Jetty 9.4+ based HTTP engine. The Jetty implementation is newer and lessl tested, but if may end up being a good choice when relying on Jetty as server side already. The Jetty Server can even share execution resources with Client libraries if you configure them to use e.g. the same QueuedThreadPool.

The Jetty engine is enabled by adding a dependency to the org.jboss.resteasy:resteasy-client-jetty artifact to the Maven project; then the client can be built as follows:

       ResteasyClient client = new ResteasyClientBuilder().clientEngine(
          new JettyClientEngine(new HttpClient())).build();