Skip to main content

juneau-rest-client Basics

Maven Dependency

<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-client</artifactId>
<version>${juneau.version}</version>
</dependency>

Java Library

juneau-rest-client-0.0.0.jar

OSGi Module

org.apache.juneau.rest.client_0.0.0.jar

Contents/Features

Built upon the feature-rich Apache HttpClient library, the Juneau RestClient API adds support for fluent-style REST calls and the ability to perform marshalling of POJOs to and from HTTP parts.

Example
// Create a basic REST client with JSON support and download a bean.
MyBean bean = RestClient.create()
.json5()
.build()
.get(URI)
.run()
.assertStatus().asCode().is(200)
.assertHeader("Content-Type").matchesSimple("application/json*")
.getContent().as(MyBean.class);

Breaking apart the fluent call, we can see the classes being used:

RestClient.Builder builder = RestClient.create().json5();
RestClient client = builder.build();
RestRequest req = client.get(URI);
RestResponse res = req.run();
RestResponseStatusLineAssertion statusLineAssertion = res.assertStatus();
FluentIntegerAssertion codeAssertion = statusLineAssertion.asCode();
res = codeAssertion.is(200);
FluentStringAssertion headerAssertion = res.assertHeader("Content-Type");
res = headerAssertion.matchesSimple("application/json*");
ResponseContent content = res.getContent();
MyBean bean = content.as(MyBean.class);

It additionally provides support for creating remote proxy interfaces using REST as the transport medium.

Example
// Define a Remote proxy for interacting with a REST interface.
@Remote(path="/petstore")
public interface PetStore {

@RemotePost("/pets")
Pet addPet(
@Content CreatePet pet,
@Header("E-Tag") UUID etag,
@Query("debug") boolean debug
);
}

PetStore store = RestClient
.create()
.json5()
.build()
.getRemote(PetStore.class, "http://localhost:10000");
CreatePet createPet = new CreatePet("Fluffy", 9.99);
Pet pet = store.addPet(createPet, UUID.randomUUID(), true);

The classes are closely tied to Apache HttpClient, yet provide lots of additional functionality:

REST Client Class HierarchyRestClient implements HttpClient, creates RestRequest objectsRestRequest implements HttpUriRequest, creates RestResponse objectsRestResponse implements HttpResponse, creates ResponseContent and ResponseHeader objectsResponseContent implements HttpEntity

Instances of this class are built using the RestClient.Builder class which can be constructed using the RestClient.create() method as shown above.

Clients are typically created with a root URI so that relative URIs can be used when making requests.

This is done using the RestClient.Builder.rootUrl(Object) method.

Example
// Create a client where all URIs are relative to localhost.
RestClient client = RestClient.create().json().rootUrl("http://localhost:10000").build();

// Use relative paths.
String content = client.get("/subpath").run().getContent().asString();

The RestClient class creates RestRequest objects using the following methods:

RestClientget(uri) / get()put(uri,body) / put(uri)post(uri,body) / post(uri)patch(uri,body) / patch(uri)delete(uri)head(uri)options(uri)formPost(uri,body) / formPost(uri)formPostPairs(uri,parameters...)request(method,uri,body)

The RestRequest class creates RestResponse objects using the following methods:

RestRequestrun()complete()

The distinction between the two methods is that complete() automatically consumes the response body and run() does not.

Note that you must consume response bodies in order for HTTP connections to be freed up for reuse!

The InputStreams returned by the ResponseContent object are auto-closing once they are exhausted, so it is often not necessary to explicitly close them.

The following examples show the distinction between the two calls:

// Consuming the response, so use run().
String content = client.get(URI).run().getContent().asString();

// Only interested in response status code, so use complete().
int status = client.get(URI).complete().getStatusCode();

Resource Management with Try-With-Resources

Both RestRequest and RestResponse implement AutoCloseable and can be used in try-with-resources blocks for automatic resource cleanup.

Recommended Pattern

Use try-with-resources to ensure proper cleanup of HTTP connections:

// RestRequest will automatically close the response when the try block exits
try (RestRequest req = client.get(URI)) {
String content = req.run().getContent().asString();
}

// Or explicitly manage both request and response
try (RestRequest req = client.get(URI);
RestResponse res = req.run()) {
String content = res.getContent().asString();
}

The close() methods follow these rules:

  • Unchecked exceptions (RuntimeException and Error) are allowed to propagate for debuggability
  • Checked exceptions are caught and logged but not thrown, following AutoCloseable best practices

This design prevents close exceptions from masking the original exception while still making programming errors visible during development.