An highly scalable adapter for Retrofit.
The Retrofit Vert.x Adapter allows to use Retrofit with the Vert.x library.
Vert.x is a library that provides an highly scalable HTTP client that features
-
HTTP/1 or HTTP/2 transport
-
Connection pooling
-
SSL / TLS
-
Proxy support
-
Non blocking DNS resolution
-
Native SSL support (OpenSSL, BoringSSL, etc…)
Intro
Retrofit turns your HTTP API into a Java interface.
public interface GitHubService {
@GET("/repos/{owner}/repos")
Call<List<Repo>> listRepos(@Path("user") String owner);
}
The Retrofit class generates an implementation of the GitHubService interface.
The VertxCallFactory
implements Retrofit CallAdapter
delegating to a Vert.x HttpClient
.
Vertx vertx = Vertx.vertx();
HttpClient client = vertx.createHttpClient();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.callFactory(new VertxCallFactory(client))
.build();
GitHubService service = retrofit.create(GitHubService.class);
Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.
Call<List<Repo>> repos = service.listRepos("octocat");
Usage
<dependency>
<groupId>com.julienviet</groupId>
<artifactId>retrofit-vertx</artifactId>
<version>1.1.3</version>
</dependency>
This version is for Retrofit 2.4.0 and Vert.x 3.5.4
Going asynchronous
You can call the execute
method to perform a blocking http call on the current thread, or you can also enqueue
an asynchronous call.
repos.enqueue(new Callback<List<Repo>>() {
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
// Response is on Vert.x event loop thread
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
// Failure is on Vert.x event loop thread
}
});
Vert.x concurrency model is based on the reactor pattern, you can read more at http://vertx.io/docs/vertx-core/java/#_reactor_and_multi_reactor
Using with RxJava
Retrofit provides an RxJava adapter you can use, to use it add the adapter library to your build file:
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>adapter-rxjava</artifactId>
<version>2.3.0</version>
</dependency>
using is quite straightforward
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.callFactory(new VertxCallFactory(client))
.addCallAdapterFactory(RxJavaCallAdapterFactory.createAsync())
.build();
GitHubService service = retrofit.create(GitHubService.class);
Single<ResponseBody> single = retrofit.create(GitHubService.class).body();
single.subscribe(result -> {
// Callback on Vert.x event loop thread
}, error -> {
// Error on Vert.x event loop thread
});
Note
|
there is also an RxJava 2 adapter that works equally well |
TLS/SSL configuration
Configuring TLS/SSL with a Java truststore is done when creating the client
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
.setSsl(true)
.setTrustStoreOptions(
new JksOptions()
.setPath("/path/to/truststore")
.setPassword("the-password")));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.callFactory(new VertxCallFactory(client))
.build();
GitHubService service = retrofit.create(GitHubService.class);
you can also use PKCS12 files
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
.setSsl(true)
.setPfxTrustOptions(
new PfxOptions()
.setPath("/path/to/pfxstore")
.setPassword("the-password"))); (io.vertx.core.Vertx)}
or even PEM files
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
.setSsl(true)
.setPemTrustOptions(
new PemTrustOptions()
.addCertPath("/path/to/pem1")
.addCertPath("/path/to/pem2")
.addCertPath("/path/to/pem3")));
HTTP/2 support
You can configure the client to use HTTP/2 protocol by setting the alpn
and protocol
options:
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
.setUseAlpn(true)
.setProtocolVersion(HttpVersion.HTTP_2)
.setSsl(true)
.setTrustStoreOptions(
new JksOptions()
.setPath("/path/to/truststore")
.setPassword("the-password")));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.callFactory(new VertxCallFactory(client))
.build();
GitHubService service = retrofit.create(GitHubService.class);
You need also to configure ALPN for your JVM, you should http://vertx.io/docs/vertx-core/java/#ssl
Proxy support
You can configure the client to use a HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy.
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
.setProxyOptions(new ProxyOptions()
.setType(ProxyType.SOCKS5)
.setHost("localhost")
.setPort(1080)
.setUsername("username")
.setPassword("secret")));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.callFactory(new VertxCallFactory(client))
.build();
GitHubService service = retrofit.create(GitHubService.class);
To know more about proxy support, you should read you should read http://vertx.io/docs/vertx-core/java/#_using_a_proxy_for_client_connections