MicroProfile Rest Client for RESTful communication

Last Updated:  July 6, 2020 | Published: July 8, 2019

In one of my recent blog posts, I presented Spring's WebClient for RESTful communication. With Java EE we can utilize the JAX-RS Client and WebTarget classes to achieve the same. However, if you add the MicroProfile API to your project, you can make use of the MicroProfile Rest Client specification. This API targets the following goal:

The MicroProfile Rest Client provides a type-safe approach to invoke RESTful services over HTTP. As much as possible the MP Rest Client attempts to use JAX-RS 2.0 APIs for consistency and easier re-use.

With MicroProfile 3.3 you'll get the latest version of the Rest Client which is 1.4. RESTful communication becomes quite easy  with this specification as you just define the access to an external REST API with an interface definition and JAX-RS annotations:

In this blog post, I'll demonstrate an example usage of MicroProfile Rest Client using Java EE, MicroProfile, Java 8 running on Payara.

System architecture

The project contains two services: order application and user management application. Alongside order data, the order application also stores the id of the user who created this order. To resolve a username from the user id and to create new orders the application accesses the user management application's REST interface:

microProfileRestClientBlogArchitecture

For simplicity, I keep the implementation simple and store the objects in memory without an underlying database.

MicroProfile project setup

Both applications were created with my Java EE 8 and MicroProfile Maven archetype and contain just both APIs:

The order application has two JAX-RS endpoints, one for reading orders by their id and one for creating an order:

The user management application has also two JAX-RS endpoints to resolve a username by its id and to create a new user. Both of these endpoints are required for the order application to work properly and are synchronously called:

For a more advanced use case, I'm tracking the access to /users/{userId} by printing two custom HTTP headers X-Request-Id and X-Application-Name. In addition, posting a new user requires authentication and authorization which is basic authentication for which I'm using the Java EE 8 Security API.

Invoke RESTful services over HTTP with Rest Client

The REST access to the user management app is specified with a Java interface:

Every method of this interface represents one REST endpoint of the external service. With the common JAX-RS annotations like @GET, @POST, @Path, and @PathParam you can specify the HTTP method and URL parameters. The return type of the method represents the HTTP response body which is deserialized using the MessageBodyReader which is makes use of JSON-B for application/json. For sending data alongside the HTTP request body, you can add a POJO as the method argument.

Furthermore, you can add HTTP headers to your calls by using either @HeaderParam or @ClientHeaderParam. With @HeaderParam you mark a method argument as an HTTP header and can pass it from outside to the Rest Client. The @ClientHeaderParam on the other side does not modify the method signature with an additional argument and retrieves its value either by config, by a hardcoded string, or by calling a method. In this example, I'm using it to add the X-Application-Name  header to every HTTP request and for the authorization header which is required for basic auth. You can use this annotation on both class and method level.

Rest Client configuration and CDI integration

To integrate this Rest Client with CDI and make it injectable, you can register the client with @RegisterRestClient. Any other bean can now inject the Rest Client with the following code:

The URL of the remote service is configured either with the @RegisterRestClient(baseUri="http://somedomain/api") annotation or using the MicroProfile Config API. For this example, I'm using the configuration approach with a microprofile-config.properties file:

Besides the URL you can configure the HTTP connect and read timeouts for this Rest Client and specify JAX-RS providers to intercept the requests/responses. For more information have a look at the specification document.

As I'm using docker-compose for deploying the two applications, I can use the name of the user app for external access:

For further information have a look at the GitHub repository of this specification and the release page to get the latest specification documents.

You can find the source code with a step-by-step guide to start the two applications on GitHub.

For more information on Eclipse MicroProfile, take a look at my Getting Started with Eclipse MicroProfile Course Bundle.

Have fun using the MicroProfile Rest Client API,

Phil

>