DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • GraphQL vs REST API: Which Is Better for Your Project in 2025?
  • Build a REST API With Just 2 Classes in Java and Quarkus
  • Efficient Data Management With Offset and Cursor-Based Pagination in Modern Applications
  • Building a MongoDB-Powered RESTful Application With Quarkus and Eclipse JNoSQL

Trending

  • Building a DevOps-Ready Internal Developer Platform: A Hands-On Guide to Golden Paths, Self-Service, and Automated Delivery Pipelines
  • Migrate a Hardcoded LangGraph Agent to LaunchDarkly AI Configs in 20 Minutes
  • Why DDoS Protection Is an Architectural Decision for Developers
  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Invoking REST APIs Asynchronously With Quarkus

Invoking REST APIs Asynchronously With Quarkus

By 
Niklas Heidloff user avatar
Niklas Heidloff
·
Apr. 27, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
17.5K Views

Join the DZone community and get the full member experience.

Join For Free

Recently I blogged about how to develop reactive REST APIs with Quarkus. Developing the actual endpoints asynchronously is the first step. To leverage reactive capabilities maximally though, the complete code path should be asynchronous, especially long lasting operations like database accesses and REST API invocations. This article describes two options how to invoke REST APIs asynchronously with Quarkus.

Two Options to Invoke REST APIs Asynchronously

Here are the two options:

  • Eclipse MicroProfile REST Client
  • Eclipse Vert.x Axle Web Client

The question is when to use which option. Rather than trying to answer this myself, let me refer to Clement Escoffier, the reactive expert in the Quarkus team. Clement answered this question on StackOverflow:

  • The MicroProfile Rest Client is not non-blocking. The Vert.x web client is.
  • If the rest of your code uses RX Java, the Vert.x client has a neat RX Java API.
  • The MicroProfile Rest Client is using an annotation-driven approach, the Vert.x client is API-driven.

You can use both options in the same application which is what I’ve done in the sample application that is included in the cloud-native-starter project. The sample application uses several microservices. The web-api service invokes the articles service which I’ll describe below.

Eclipse Vert.x Axle Web Client

The Quarkus guide Using Eclipse Vert.x describes how to use the Vert.x client. Let’s take a look at the codeto invoke the articles service from the web-api service.

Java
 




x
37


 
1
import io.vertx.axle.core.Vertx;
2
import io.vertx.axle.ext.web.client.WebClient;
3
import io.vertx.ext.web.client.WebClientOptions;
4
import io.vertx.core.json.JsonObject;
5
import io.vertx.core.json.JsonArray;
6
import javax.annotation.PostConstruct;
7
import java.util.concurrent.CompletableFuture;
8
...
9
@Inject
10
Vertx vertx;
11
private WebClient client;
12
 
13
@PostConstruct
14
void initialize() {             
15
  this.client = WebClient.create(vertx, new WebClientOptions().setDefaultHost(ARTICLES_DNS).setDefaultPort(ARTICLES_PORT).setSsl(false));
16
}
17
 
18
public CompletableFuture<List<CoreArticle>> getArticlesReactiveVertxWebClient(int amount) {     
19
  CompletableFuture<List<CoreArticle>> future = new CompletableFuture<>();
20
  this.client.get("/v2/articles?amount=" + amount)
21
    .send()
22
    .toCompletableFuture() 
23
    .orTimeout(MAXIMAL_DURATION, TimeUnit.MILLISECONDS)
24
    .thenAccept(resp -> {
25
      if (resp.statusCode() == 200) {
26
        List<CoreArticle> articles = this.convertJsonToCoreArticleList(resp.bodyAsJsonArray());
27
        future.complete(articles);
28
      } else {
29
        future.completeExceptionally(new NoConnectivity());
30
      }
31
    })
32
    .exceptionally(throwable -> {
33
      future.completeExceptionally(new NoConnectivity());
34
      return null;
35
    });
36
    return future;
37
}



The methods ‘get’ and ‘send’ invoke the HTTP request. I’ve explained in my previous article why ‘toCompletableFuture’ and ‘orTimeout’ or used.

Once the request has been completed, the HTTP status code has to be checked and converted into a Java exception. If the request has been successful, the response will be a io.vertx.core.json.JsonArray or io.vertx.core.json.JsonObject. These objects need to be converted manually into Java objects, in this example in a list of articles.

Eclipse MicroProfile REST Client

The second option is to use the MicroProfile REST Client. Check out my previous blog Invoking REST APIs from Java Microservices which explains how to invoke REST APIs synchronously.

The MicroProfile REST Client has been extended to also support asynchronous invocations. There is an OpenLiberty guide Consuming RESTful services asynchronously that describes this functionality.

Again, let’s take a look at the code. First you need to define an interface to the service you want to invoke:

Java
 




xxxxxxxxxx
1


 
1
import java.util.concurrent.CompletionStage;
2
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
3
...
4
@RegisterProvider(ExceptionMapperArticles.class)
5
public interface ArticlesServiceReactive {
6
  @GET
7
  @Produces(MediaType.APPLICATION_JSON)
8
  public CompletionStage<List<CoreArticle>> getArticlesFromService();
9
}



In this interface an exception mapper class is defined. This class maps HTTP errors to Java exceptions (see code):

Java
 




xxxxxxxxxx
1
17


 
1
import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
2
...
3
@Provider
4
public class ExceptionMapperArticles implements ResponseExceptionMapper<InvalidArticle> {
5
  @Override
6
  public boolean handles(int status, MultivaluedMap<String, Object> headers) {
7
    return status == 204;
8
  }
9
  @Override
10
  public InvalidArticle toThrowable(Response response) {
11
    switch (response.getStatus()) {
12
      case 204:
13
        return new InvalidArticle();
14
      }
15
      return null;
16
    }
17
}



In order to invoke the REST API, a normal Java method can be called. The implementation of this method handles MicroProfile magically (see code):

Java
 




xxxxxxxxxx
1
21


 
1
public CompletableFuture<List<CoreArticle>> getArticlesReactive(int amount) {       
2
  CompletableFuture<List<CoreArticle>> future = new CompletableFuture<>();
3
  URL apiUrl;
4
  try {
5
    apiUrl = new URL("http://" + ARTICLES_DNS + ":" + ARTICLES_PORT + "/v2/articles?amount=" + amount);
6
    ArticlesServiceReactive articlesServiceReative = RestClientBuilder.newBuilder().baseUrl(apiUrl).build(ArticlesServiceReactive.class);
7
    articlesServiceReative.getArticlesFromService()
8
      .toCompletableFuture()
9
      .orTimeout(MAXIMAL_DURATION, TimeUnit.MILLISECONDS)   
10
      .thenAccept((articles) -> {
11
        future.complete(articles);
12
      })
13
      .exceptionally((throwable) -> {
14
        future.completeExceptionally(new NoConnectivity());
15
        return null;
16
      });
17
    } catch (MalformedURLException e) {
18
      future.completeExceptionally(new NoConnectivity());
19
    }
20
  return future;
21
}



Note that the deserialization of the JSON response into a list of articles is done automatically.

Closing Thoughts

My two cents: If you are not an experienced Rx Java developer, I’d go with MicroProfile for asynchronous REST invocations. The MicroProfile model is nicely designed, you don’t have to convert objects manually and it’s not blocking.

All samples of this article are included in the open source project cloud-native-starter. Check it out to see the code in action.

This article is part of a series. Read the other articles of this series to learn about reactive programming:

  • Development of Reactive Applications with Quarkus
  • Accessing Apache Kafka from Quarkus
  • Accessing PostgreSQL in Kubernetes from Quarkus
  • Reactive Messaging Examples for Quarkus
  • Developing reactive REST APIs with Quarkus
  • Comparing synchronous and asynchronous Access to Postgres
REST Web Protocols Quarkus

Published at DZone with permission of Niklas Heidloff. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • GraphQL vs REST API: Which Is Better for Your Project in 2025?
  • Build a REST API With Just 2 Classes in Java and Quarkus
  • Efficient Data Management With Offset and Cursor-Based Pagination in Modern Applications
  • Building a MongoDB-Powered RESTful Application With Quarkus and Eclipse JNoSQL

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook