juneau-shaded-rest-client
The juneau-shaded-rest-client artifact bundles all core Juneau modules plus REST client functionality. At 3.8 MB, it provides everything needed for building REST client applications.
What's Included
This artifact includes:
- All modules from juneau-shaded-core (marshalling, config, testing)
- juneau-rest-common - REST APIs common to client and server
- juneau-rest-client - Full-featured REST client API
- juneau-rest-mock - REST testing utilities
Use Cases
Use juneau-shaded-rest-client when you need:
- REST API consumption - Call external REST services
- Type-safe clients - Use remote interfaces and proxies
- Advanced HTTP features - Interceptors, authentication, retries
- Serialization flexibility - Automatic content negotiation
- Testing REST endpoints - Use the mock REST framework
Maven Dependency
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-shaded-rest-client</artifactId>
<version>${juneau.version}</version>
</dependency>
Bazel Dependency
maven_jar(
name = "juneau_rest_client",
artifact = "org.apache.juneau:juneau-shaded-rest-client:${juneau.version}",
)
# External dependencies
maven_jar(
name = "httpclient5",
artifact = "org.apache.httpcomponents.client5:httpclient5:5.2.1",
)
maven_jar(
name = "httpcore5",
artifact = "org.apache.httpcomponents.core5:httpcore5:5.2.1",
)
java_binary(
name = "my_client",
srcs = ["MyClient.java"],
deps = [
"@juneau_rest_client//jar",
"@httpclient5//jar",
"@httpcore5//jar",
],
)
External Dependencies
juneau-shaded-rest-client requires:
Required
- Apache HttpClient 5.2+ - HTTP client implementation
- Apache HttpCore 5.2+ - HTTP core functionality
Optional
- Jakarta XML Bind API 3.0+ - For XML serialization
- Apache Jena - For RDF support
Example Usage
Basic REST Call
import org.apache.juneau.rest.client.*;
public class RestClientExample {
public static void main(String[] args) {
try (RestClient client = RestClient.create().build()) {
// GET request
Person person = client.get("http://api.example.com/person/1")
.run()
.getContent().as(Person.class);
System.out.println(person.getName());
}
}
}
POST with JSON
try (RestClient client = RestClient.create().json().build()) {
Person newPerson = new Person("John Smith", 42);
// POST JSON
Person created = client.post("http://api.example.com/person")
.content(newPerson)
.run()
.getContent().as(Person.class);
System.out.println("Created: " + created.getId());
}
Remote Proxies
// Define interface
@Remote(path="/petstore")
public interface PetStore {
@RemoteGet("/pet/{petId}")
Pet getPet(@Path("petId") long id);
@RemotePost("/pet")
Pet createPet(@Content Pet pet);
}
// Use it
try (RestClient client = RestClient.create().build()) {
PetStore store = client.getRemote(PetStore.class);
Pet pet = store.getPet(123);
System.out.println(pet.getName());
}
Try-With-Resources Pattern
RestClient client = RestClient.create().build();
try (RestRequest req = client.get("/api/data")) {
String response = req.run().getContent().asString();
System.out.println(response);
} // Request and response are automatically closed
Authentication
// Basic authentication
RestClient client = RestClient.create()
.basicAuth("user", "password")
.build();
// Bearer token
RestClient client = RestClient.create()
.headerData("Authorization", "Bearer " + token)
.build();
// OAuth2
RestClient client = RestClient.create()
.oauth2Bearer(tokenSupplier)
.build();
Interceptors
RestClient client = RestClient.create()
.interceptors(
// Log requests
(req) -> System.out.println("Calling: " + req.getUri()),
// Add custom headers
(req) -> req.header("X-Custom", "value"),
// Retry logic
RetryInterceptor.create().maxAttempts(3).build()
)
.build();
Mock Testing
import org.apache.juneau.rest.mock.*;
@Test
public void testRestClient() throws Exception {
MockRestClient client = MockRestClient.create(MyRestApi.class).build();
// Call the mocked API
String response = client.get("/test")
.run()
.getContent().asString();
assertEquals("expected", response);
}
Features
Content Negotiation
Automatic serialization/deserialization based on Accept and Content-Type headers:
// Request JSON, get POJO
Person person = client.get("/person/1")
.accept("application/json")
.run()
.getContent().as(Person.class);
Error Handling
try (RestClient client = RestClient.create().build()) {
String response = client.get("/api/data")
.run()
.assertStatus().is(200) // Assert successful
.getContent().asString();
} catch (RestCallException e) {
System.err.println("HTTP " + e.getResponseCode());
System.err.println(e.getResponseMessage());
}
Request/Response Assertions
client.get("/api/data")
.run()
.assertStatus().is(200)
.assertHeader("Content-Type").is("application/json")
.assertContent().contains("expected");
Performance Characteristics
- Connection Pooling: Built-in via Apache HttpClient
- Keep-Alive: Automatic connection reuse
- Streaming: Efficient memory usage for large responses
- Async Support: Non-blocking operations available
Migration from Individual Modules
Before:
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-marshall</artifactId>
<version>${juneau.version}</version>
</dependency>
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-client</artifactId>
<version>${juneau.version}</version>
</dependency>
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-rest-common</artifactId>
<version>${juneau.version}</version>
</dependency>
After:
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-shaded-rest-client</artifactId>
<version>${juneau.version}</version>
</dependency>
Next Steps
- Need server functionality too? Use juneau-shaded-all
- Learn about REST client: See REST Client Basics
- Learn about remote proxies: See Remote Proxies
- Learn about marshalling: See Marshalling Basics
Share feedback or follow-up questions for this page directly through GitHub.