Calling Microservices in Java: Part 1

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!

Promoted Content

Your tests failed again?

Beyond pass/fail, insights from tests are priceless. Get a clear view of your tests related to each asset – code, query, or client.


Get Insights

The post Calling Microservices in Java: Part 1 appeared first on foojay.