MicroProfile Rest Client 2.0 – First Look
Andy McCright
Posted on May 4, 2021
The latest release of MicroProfile’s type-safe REST client has a lot of new and exciting features. In this post, we’ll take a look at some of the new features and how you can use them in Open Liberty, including:
- Using QueryParamStyle to specify how collections of query parameters should be formatted
- Proxy server support
- Automatically following redirects
- Support for Server Sent Events (SSEs)
Getting started
The MicroProfile Rest Client 2.0 implementation is new in Open Liberty 21.0.0.3 – so make sure you are using the latest version of Liberty. Next, you will need to add the following Maven dependency to your pom.xml:
<dependency>
<groupId>org.eclipse.microprofile.rest.client</groupId>
<artifactId>microprofile-rest-client-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
or, if you use Gradle:
dependencies {
compileOnly group: 'org.eclipse.microprofile.rest.client', name: 'microprofile-rest-client-api', version: '2.0'
}
Also, make sure to configure your Liberty server with the mpRestClient-2.0
feature in the server.xml:
<server>
<featureManager>
<feature>mpRestClient-2.0</feature>
<!-- ... -->
</featureManager>
<!-- ... -->
</server>
That’s it! Now that we’ve got our development and deployment environments set up, it’s time to code!
Using QueryParamStyle to specify how collections of query parameters should be formatted
Rest Client interfaces can specify query parameters using the @QueryParam("paramName")
annotation, but often a server will require that multi-valued query parameters must be formatted in a certain way. For example, suppose we have a client interface like:
@RegisterRestClient
public interface MyClient {
@GET
String multiValues(@QueryParam("myParam") List<String> values);
}
By default, if a caller invokes the client with multiValues(Arrays.asList("a", "b", "c"))
the MP Rest Client will produce an HTTP request with multiple key/value pairs – something like:
?myParam=a&myParam=b&myParam=c
.
Although most servers will handle that just fine, some servers might require the HTTP request to be a single key with a comma-separated list of values, like:
?myParam=a,b,c
.
Still other servers will require array-like syntax, such as:
?myParam[]=a&myParam[]=b&myParam[]=c
.
In order to support those other server types, you can now use the QueryParamStyle
enum when building the client instance – for example:
MyClient client = RestClientBuilder.newBuilder()
.queryParamStyle(QueryParamStyle.COMMA_SEPARATED)
//...
.build(MyClient.class);
Alternatively, you can declare the query parameter style through MP Config by using a property like:
com.mypkg.MyClient/mp-rest/queryParamStyle=ARRAY_PAIRS
The following table lists the QueryParamStyle
enum values and provides an example of the corresponding output for each value.
Enum Value | Output Example |
---|---|
MULTI_PAIRS (default) | ?myParam=a&myParam=b&myParam=c |
COMMA_SEPARATED | ?myParam=a,b,c |
ARRAY_PAIRS | ?myParam[]=a&myParam[]=b&myParam[]=c |
Proxy server support
You might need to use a proxy server to access some RESTful endpoints. MicroProfile Rest Client 2.0 makes it easier and more portable to specify a proxy server with the new proxyAddress(host, port)
method on the RestClientBuilder
class. For example, suppose you need to access an endpoint via a proxy server at myproxy.xyz.com
on port 1080
. You could build your rest client instance with code like:
MyClient client = RestClientBuilder.newBuilder()
.proxyAddress("myproxy.xyz.com", 1080)
//...
.build(MyClient.class);
Alternatively, you can specify the proxy address via MP Config with a property like:
com.mypkg.MyClient/mp-rest/proxyAddress=myproxy.xyz.com:1080
Note that for portability, this approach to setting the proxy server host and port is preferred to using vendor-specific properties such as com.ibm.ws.jaxrs.client.proxy.host
and com.ibm.ws.jaxrs.client.proxy.port
, though these properties will still work. For proxy authentication, you can still use the com.ibm.ws.jaxrs.client.proxy.username
and com.ibm.ws.jaxrs.client.proxy.password
properties. For example:
MyClient client = RestClientBuilder.newBuilder()
.proxyAddress("myproxy.xyz.com", 1080)
.property("com.ibm.ws.jaxrs.client.proxy.username", "andymc12")
.property("com.ibm.ws.jaxrs.client.proxy.password", "12345") //same as my luggage! ![🙂](https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png)
//...
.build(MyClient.class);
Automatically following redirects
If a RESTful resource has been relocated, often the HTTP response code will be in the 300 range and will indicate the new location. Rather than handling the 3XX response and manually issuing a new request, MP Rest Client 2.0 allows rest client instances to automatically follow redirects. You can configure a client to automatically follow redirects either programmatically, when you build the client instance, or via MP Config. Here is an example of configuring auto-redirect via the RestClientBuilder
API:
MyClient client = RestClientBuilder.newBuilder()
.followRedirects(true)
//...
.build(MyClient.class);
And here is how you would configure it via MP Config:
com.mypkg.MyClient/mp-rest/followRedirects=true
Support for Server Sent Events
Server Sent Events (SSE), part of the HTML 5 spec, enable a server to push data to a client asynchronously via events, over HTTP. The JAX-RS 2.1 spec enabled SSE support for both the client and server. Now you can consume SSE events from the type-safe MP Rest Client.
The MP Rest Client specification uses the Reactive Streams APIs to consume events. A client interface capable of consuming SSEs looks something like this:
@RegisterRestClient
public interface SseClient {
@GET
@Path("/path/sse")
@Produces(MediaType.SERVER_SENT_EVENTS)
Publisher<String> getStrings();
@GET
@Path("/path/sse2")
@Produces(MediaType.SERVER_SENT_EVENTS)
Publisher<InboundSseEvent> getEvents();
}
First, the method (or interface) must be annotated with @Produces(MediaType.SERVER_SENT_EVENTS)
to indicate that it expects the server to produce SSEs. Next, the method’s return type must be org.reactivestreams.Publisher
. The generic type can be javax.ws.rs.sse.InboundSseEvent
(from JAX-RS), a primitive, a String, or a complex type. Complex types can only be used if:
1) the server only sends one type of event (e.g. only sends WeatherEvents
– then Publisher<WeatherEvent>
would be applicable)
and
2) there is a registered entity provider capable of converting the events (e.g. MessageBodyReader<WeatherEvent>
).
In most cases, if the remote server sends events using JSON, you can enable the jsonb-1.0
feature in your Liberty server, which will automatically register a JSON-B-based entity provider.
Once you invoke one of these methods, you can register one or more Subscriber
instances to the Publisher
. Each subscriber will be notified on receipt of a new event or if the connection to the server has been closed.
Summary
MicroProfile Rest Client 2.0 has some powerful new features that are useful for building cloud native applications. You can read more about these updates on the MP Rest Client 2.0 release page.
MicroProfile Rest Client 2.0 is part of the larger MicroProfile 4.0 release. If you’d like to learn more about the other technologies in MicroProfile 4.0, check out this deep dive blog post.
As always, let us know if you have any questions with this new feature. Thanks for checking it out!
Originally posted on March 24, 2021 at:
https://openliberty.io/blog/2021/03/24/whats-new-in-MP-Rest-Client2.0.html
Posted on May 4, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.