List of Rest clients in the Java Ecosystem
Introduction
- REST APIs have been the center of integration for disparate systems. Java Ecosystem has seen different flavors of Rest Client( native + third party ) that allow consuming these RestFul APIs with abstractions.
- Design for the Rest Client has been influenced by technology, best practices, and the need for developers to build RESTful web applications.
- In this article, we will cover the evolution of Java Rest Client.
1.HttpURLConnection
- In the early days of Java low-level libraries such as `java.net.HttpURLConnection` were mostly used.
- The major problem with using HttpURLConnection is the lack of abstraction. Writing HTTP requests and handling responses required too much boilerplate code and manual.
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Java HttpURLConnection");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
// Process the response content
System.out.println(response.toString());
}
connection.disconnect();
2. Apache HttpClient
- Apache HttpClient became a popular choice for writing rest clients in Java due to its abstraction for writing requests, managing connections, and handling responses.
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://example.com");
HttpResponse response = client.execute(request);
// Get the response
BufferedReader rd = new BufferedReader
(new InputStreamReader(
response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
textView.append(line);
}
3. JAX-RS/Jersey Client API
- Java API for RESTFul web services ( JAX-RS ) introduced the `Client` API as part of the Java EE standard.
- It offered a high-level and more declarative approach for building REST client. Developers could define client interfaces and use annotation to define request and response mappings.
- Jersey is a popular JAX-RS implementation and includes its own client API.
- It provided a convenient way to consume RESTFul APIs.
Sample Request Response Code:
public class RestClient {
private static final String REST_URI
= "http://localhost:8082/resources/task";
private Client client = ClientBuilder.newClient();
public Task getTaskById(int id) {
return client
.target(REST_URI)
.path(String.valueOf(id))
.request(MediaType.APPLICATION_JSON)
.get(Task.class);
}
//...
}
4. Spring Rest Template
- Spring Framework provided `RestTemplate` class as part of the web module.
- Due to its simplified approach in writing and handling related tasks, it became the default choice in spring-based applications.
public class RestTemplateExample {
public static void main(String[] args) {
// Create a RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// Send a GET request and receive the response
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://example.com", String.class);
// Extract the response body
String responseBody = responseEntity.getBody();
// Process the response
System.out.println("Response: " + responseBody);
}
}
5. Spring WebClient
- Due to the popularity of asynchronous programming and reactive programming, Spring introduced the `WebClient` class as part of the Spring WebFlux framework.
- This non-blocking HTTP client allowed developers to make asynchronous and reactive REST calls.
import org.springframework.web.reactive.function.client.WebClient;
public class WebClientExample {
public static void main(String[] args) {
// Create a WebClient instance
WebClient webClient = WebClient.create("http://example.com");
// Send a GET request and retrieve the response
String responseBody = webClient.get()
.uri("/posts/1")
.retrieve()
.bodyToMono(String.class)
.block();
// Process the response
System.out.println("Response: " + responseBody);
}
}
6. Apache HttpClient 5
- Apache HttpClient went under significant changes in version 5. HttpClient 5 introduced more modern and modular architecture and made it more suitable for modern Java applications.
- It also embraced the changes introduced in Java 11 and later version.
public class HttpClient5Example {
public static void main(String[] args) throws Exception {
// Create a custom HttpClient instance
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.build())
.build();
// Create an HttpGet request
HttpUriRequestBase request = new HttpGet("http://example.com/posts/1");
// Execute the request and get the response
try (CloseableHttpResponse response = httpClient.execute(request)) {
// Check the response status code
int statusCode = response.getCode();
if (statusCode == 200) {
// Read and process the response entity
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response: " + responseBody);
} else {
System.err.println("Request failed with status code: " + statusCode);
}
}
}
}
7. OkHttp
- OkHttp is a popular third-party HTTP client library used for Java and Android.
- It’s known for its popularity related to modern features such as connection pooling, and request and response interception.
- Many developers preferred OkHttp to write and handle Http-related tasks.
public class OkHttpExample {
public static void main(String[] args) throws IOException {
// Create an OkHttpClient instance
OkHttpClient client = new OkHttpClient();
// Create a request
Request request = new Request.Builder()
.url("http://example.com/posts/1")
.build();
// Send the request and receive the response
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
// Read and process the response body
String responseBody = response.body().string();
System.out.println("Response: " + responseBody);
} else {
System.err.println("Request failed with status code: " + response.code());
}
}
}
}
8. Java 11+ HTTP Client
- Starting Java 11, a new standard HTTP client library was introduced as part of
java.net.http
package. - This native client is asynchronous and supports HTTP/2, WebSocket, and reactive programming.
- It provided modern built-in features that obsolete the use of third-party libraries for handling HTTP-related tasks.
public class HttpClientExample {
public static void main(String[] args) throws IOException {
HttpClient httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
URI uri = URI.create("http://example.com/posts/1");
HttpRequest request = HttpRequest.newBuilder()
.GET() // or use .POST() for POST requests
.uri(uri)
.header("User-Agent", "Java 11 HttpClient Example")
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
int statusCode = response.statusCode();
HttpHeaders headers = response.headers();
String responseBody = response.body();
System.out.println("Status Code: " + statusCode);
System.out.println("Response Headers: " + headers);
System.out.println("Response Body: " + responseBody);
}
}
9. Feign
- Feign is a declarative HTTP client developed by Netflix. It allows developers to define HTTP clients using annotation and interfaces similar to JAX-RS.
- Feign has good integration with Spring and other frameworks.
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
@RequestLine("POST /repos/{owner}/{repo}/issues")
void createIssue(Issue issue, @Param("owner") String owner, @Param("repo") String repo);
}
public static class Contributor {
String login;
int contributions;
}
public static class Issue {
String title;
String body;
List<String> assignees;
int milestone;
List<String> labels;
}
public class MyApp {
public static void main(String... args) {
GitHub github = Feign.builder()
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");
// Fetch and print a list of the contributors to this library.
List<Contributor> contributors = github.contributors("OpenFeign", "feign");
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
}
10. Retrofit
- Retrofit is a popular third-party library for creating REST clients in Java & Android. It’s known for its simplicity and type-safe API. Developers define RESTFul API interfaces with annotation and Retrofit handles requests and response.
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
Call<List<Repo>> repos = service.listRepos("octocat");
11. Others
- Modern microservice frameworks such as micronaut and quarkus has come up with built-in support for creating efficient and lightweight REST Clients.
- They have been designed for cloud-native application and ahead-of-time compilation with minimal resource consumption.
Conclusion
- In this article We have discussed various options and evolution of Java Rest Client .
- When writing simple java based apps, For most of the use cases Java HttpClient introduced in version 11 should be enough.
- But if there specific framework that we are working on then using framework specific client make sense.
Before You Leave
- Upgrade your Java skills with Grokking the Java Interview.
- If you want to upskill your Java skills, you should definitely check out
[NEW] Master Spring Boot 3 & Spring Framework 6 with Java
[ 38 hrs content, 4.7/5 stars, 6k+ students already enrolled] - Find More Java/Spring Blogs
- Subscribe to Java/Spring Newsletter