Friends of OpenJDK Today

Calling Microservices in Java: Part 1

May 17, 2024

Author(s)

  • Muaath Bin Ali

    Muaath Ali is a principal software engineer with 15+ years of Java experience. He runs MezoCode blog, helping Java developers design flexible and robust systems.

When building applications that need to call other parts of the system (microservices), Java programmers have access to a variety of tools and techniques that they can use for their development tasks.

This article guides you through different ways of calling Microservices in Java, from basic methods to more advanced ones, and will share tips on best practices and common mistakes.

1. Basic HTTP Requests with HttpURLConnection

The simplest way to calling a microservice in Java is using the HttpURLConnection class. This lets your application send HTTP requests and receive responses directly.

Example:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class SimpleServiceCaller {
    public static String callService(String serviceUrl) throws Exception {
        URL url = new URL(serviceUrl);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");

        try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
            String inputLine;
            StringBuilder response = new StringBuilder();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            return response.toString();
        } finally {
            con.disconnect();
        }
    }
}

Pros:

  • It's simple and doesn't need extra software libraries.
  • Good for smaller applications or when you don't call services often.

Cons:

  • It lacks features like connection reuse, automatic retries, and error handling.
  • Managing HTTP connections manually can lead to mistakes and messy code.

2. Using Apache HttpClient

Apache HttpClient is a more robust tool for making HTTP calls.

It supports many advanced features like connection pooling, which means it can handle many requests efficiently, authentication, and handling proxies.

Example:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

public class ApacheHttpClientExample {
    public static String callService(String serviceUrl) throws Exception {

        try (CloseableHttpClient client = HttpClients.createDefault()) {
            HttpGet request = new HttpGet(serviceUrl);
            return client.execute(request, httpResponse -> 
                EntityUtils.toString(httpResponse.getEntity()));
        }
    }
}

Pros:

  • Handles complex HTTP interactions well.
  • Connection pooling improves performance when dealing with many requests.

Cons:

  • Adds complexity and requires additional library dependencies.
  • Still needs manual setup for error handling and resilience.

3. Using Spring’s RestTemplate and WebClient

For applications built with Spring, RestTemplate and WebClient are convenient options.

Example with RestTemplate:

import org.springframework.web.client.RestTemplate;

public class RestTemplateExample {
    private static final RestTemplate restTemplate = new RestTemplate();

    public static String callService(String serviceUrl) {
        return restTemplate.getForObject(serviceUrl, String.class);
    }
}

Example with WebClient:

import org.springframework.web.reactive.function.client.WebClient;

public class WebClientExample {
    private static final WebClient webClient = WebClient.create();

    public static String callService(String serviceUrl) {
        return webClient.get()
                        .uri(serviceUrl)
                        .retrieve()
                        .bodyToMono(String.class)
                        .block();  // Waits for the response
    }
}

Pros:

  • Easy to integrate and use within Spring applications.
  • WebClient supports modern, reactive programming.

Cons:

  • Tied to Spring, so not suitable if you’re not using this framework.
  • Spring is moving away from RestTemplate to favor WebClient.

4. Using Feign for Declarative REST Clients

Feign is a tool that lets you write very simple code to make HTTP calls by defining interfaces.

Example:

@FeignClient(name = "serviceClient", url = "https://jsonplaceholder.typicode.com/todos/1")
public interface ServiceClient {

    @GetMapping("/service")
    String callService();
}

Pros:

  • Simplifies code with its declarative style.
  • Integrates well with Spring and other modern Java tools.

Cons:

  • Less control over the details of HTTP requests.
  • Requires adding Feign libraries to your project.

Best Practices and Common Mistakes

  • Use connection pooling: It's better for performance.
  • Implement error handling: Use retries, timeouts, and circuit breakers to make your application more reliable.
  • Choose well-supported libraries like Apache HttpClient or WebClient instead of managing HTTP connections yourself.
  • Keep an eye on your HTTP traffic: Logging requests and responses help in debugging issues.
  • Secure your HTTP requests: Use HTTPS and proper authentication methods.

Conclusion

Choosing the right method to connect to microservices in Java depends on your specific needs, such as how big your application is and whether you are using Spring Framework.

While simple methods are fine for small tasks or when you don't need to call services often, more advanced techniques offer better performance and easier maintenance as your application grows.

Follow best practices to ensure your application is robust and performs well.

Happy coding!

Sponsored Content

Jakarta EE 11: Beyond the Era of Java EE

This user guide provides a brief history of Java EE/Jakarta EE and a detailed overview of some of the specifications that will be updated in Jakarta EE 11.

Get Started

Topics:

Related Articles

View All

Author(s)

  • Muaath Bin Ali

    Muaath Ali is a principal software engineer with 15+ years of Java experience. He runs MezoCode blog, helping Java developers design flexible and robust systems.

Comments (2)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

chuss

Why not have an example with Springs new RestClient?

Erwan

What about using the http client introduce in java 11 ?

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard