Evolution of Rest Client In Java

  • Post last modified:September 25, 2023
  • Reading time:7 mins read

List of Rest clients in the Java Ecosystem

Rest Client in Java Ecosytem

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();

Here is the detailed Blog.

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);
}

Here is the detailed Blog.

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);
    }
    //...
}

Here is the detailed blog.

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);
    }
}

Here is the detailed blog.

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);
    }
}

Here is the detailed blog.

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);
            }
        }
    }
}

Here is the detailed blog.

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());
            }
        }
    }
}

Here is the detailed blog.

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);
    }
}

Here is the detailed blog.

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 + ")");
    }
  }
}

Here is the detailed blog.

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");

Here is the detailed blog.

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

Leave a Reply