back to all blogsSee all blog posts

Improved developer experience and MicroProfile integration for MicroProfile Rest Client 1.2

image of author
Andy McCright on Mar 28, 2019

MicroProfile Rest Client is a type-safe client API for invoking RESTful services. Version 1.2 improves the developer experience and enhances integration with other MicroProfile technologies such as CDI, Fault Tolerance, OpenTracing, etc. MicroProfile Rest Client 1.2 is part of MicroProfile 2.2, which is available in Open Liberty 19.0.0.3.

Previous releases of MicroProfile Rest Client lacked integration with CDI, Fault Tolerance, OpenTracing, etc. making it difficult to add things like timeouts, retries, circuit breakers, etc. to client interfaces. MicroProfile Rest Client 1.2 improves integration with other MicroProfile technologies but also improves the developer experience so that you can specify the base URL directly in the @RegisterRestClient annotation in the interface and specify connect and read timeouts in a portable fashion.

Sending HTTP headers or propagating them from a JAX-RS request has been a complicated problem with prior releases, but not anymore. Now you can specify HTTP headers to send or propagate using the new @ClientHeaderParam annotation, MicroProfile Config properties, or by implementing a new ClientHeadersFactory interface.

To enable the MicroProfile Rest Client feature in your server.xml:

<featureManager>
  <feature>mpRestClient-1.2</feature>
</featureManager>

Here is an example of specifying the URI in the annotation on the interface:

package io.openliberty.rest.client;
...
@RegisterRestClient(baseUri="http://localhost:9080/myBaseUri")
public interface ClientWithURI {
...

This can still be overridden by specifying a MicroProfile Config property like this:

io.openliberty.rest.client.ClientWithURI/mp-rest/uri=http://localhost:9080/myOverriddenBaseUri

If the MicroProfile Rest Client interface is invoked from within a JAX-RS resource class, then it is possible to propagate HTTP headers from the incoming request to the outgoing Rest Client request by specifying the headers to propagate using this MP Config property:

org.eclipse.microprofile.rest.client.propagateHeaders=Authorization,MyCustomHeader

It is also possible to specify or generate a header value using annotations like this:

@ClientHeaderParam(name="HeaderOrigin", value="MPRestClientInOpenLiberty")
@ClientHeaderParam(name="MyHeader", value="value1")
@Path("/somePath")
public interface MyClient {

    @GET
    @ClientHeaderParam(name="MyHeader", value="{computeValue}")
    MyResponse getSomeResponse();

    default String computeValue() {
        return "value2";
    }
...

In this example, the client would send two newly-created HTTP headers when the getSomeResponse() method is invoked:

    HeaderOrigin: MPRestClientInOpenLiberty
    MyHeader: value2

Header values can be computed by surrounding the method name in curly-braces. The only methods that can be specified to compute a header value are default interface methods in the same client interface or public static methods (which must be fully-qualified).

In the case where the same header is specified at the interface level and the method level, the value specified at the method level is used. Thus MyHeader is set to value2 rather than value1.

If the mpFaultTolerance-2.0 feature has been specified, then the functionality of the Rest Client interfaces can be augmented with handy Fault Tolerance APIs, for example:

public interface MyFaultTolerantClient {

    @GET
    @Retry(retryOn={WebApplicationException.class}, maxRetries = 3)
    String method1();

    @PUT
    @Timeout(value=3, unit=ChronoUnit.SECONDS)
    boolean method2(MyEntity entity);

    @POST
    @Fallback(fallbackMethod="queueForLater")
    boolean method3(MyEntity entity);

    default boolean queueForLater(MyEntity entity) {
        return addToRetryQueue(entity);
    }
}

In this example, method1 retries the request up to three times in the event that a WebApplicationException occurs. The @Timeout annotation on method2 automatically sets the connect and read timeouts for the request to 3 seconds, and if the request takes longer than 3 seconds, the Fault Tolerance implementation interrupts the request. Lastly, if an exception occurs when invoking method3, the Fault Tolerance implementation invokes the queueForLater method.

To try it out, take a look at Open Liberty 19.0.0.3, which provides a full implementation of MicroProfile 2.2, including MicroProfile Rest Client 1.2.

For more details, take a look at the MicroProfile Javadoc.

To learn to use MicroProfile Rest Client, see the Consuming RESTful services with template interfaces guide.