Ark uses a bridge pattern - the transport is a thin adapter around an already configured HTTP client. Timeouts, SSL, connection pools, and HTTP version are configured on the client itself, not on Ark.
| Interface | Returns | Module |
|---|---|---|
HttpTransport |
RawResponse |
ark-core |
AsyncHttpTransport |
CompletableFuture<RawResponse> |
ark-async |
ReactorHttpTransport |
Mono<RawResponse> |
ark-reactor |
MutinyHttpTransport |
Uni<RawResponse> |
ark-mutiny |
VertxHttpTransport |
Future<RawResponse> |
ark-vertx |
A single transport can implement multiple interfaces. For example, ArkJdkHttpTransport implements both HttpTransport and AsyncHttpTransport.
| Transport | Implements | Module |
|---|---|---|
ArkJdkHttpTransport |
HttpTransport + AsyncHttpTransport |
ark-transport-jdk |
ArkReactorNettyTransport |
ReactorHttpTransport |
ark-transport-reactor |
ArkVertxFutureTransport |
VertxHttpTransport |
ark-transport-vertx |
ArkVertxMutinyTransport |
MutinyHttpTransport |
ark-transport-vertx-mutiny |
ArkApacheTransport |
HttpTransport |
ark-transport-apache |
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-jdk</artifactId>
</dependency>HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.sslContext(sslContext)
.executor(Executors.newVirtualThreadPerTaskExecutor())
.build();
ArkJdkHttpTransport transport = new ArkJdkHttpTransport(httpClient);<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-reactor</artifactId>
</dependency>reactor.netty.http.client.HttpClient httpClient = HttpClient.create()
.responseTimeout(Duration.ofSeconds(30))
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
.secure(ssl -> ssl.sslContext(sslContext));
ArkReactorNettyTransport transport = new ArkReactorNettyTransport(httpClient);<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-vertx</artifactId>
</dependency>WebClient webClient = WebClient.create(vertx, new WebClientOptions()
.setSsl(true)
.setConnectTimeout(5000)
.setMaxPoolSize(50));
ArkVertxFutureTransport transport = new ArkVertxFutureTransport(webClient);<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-vertx-mutiny</artifactId>
</dependency>io.vertx.mutiny.ext.web.client.WebClient webClient = WebClient.create(vertx);
ArkVertxMutinyTransport transport = new ArkVertxMutinyTransport(webClient);<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-apache</artifactId>
</dependency>CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
.setMaxConnTotal(100)
.setMaxConnPerRoute(20)
.build())
.setDefaultRequestConfig(RequestConfig.custom()
.setResponseTimeout(Timeout.ofSeconds(30))
.build())
.build();
ArkApacheTransport transport = new ArkApacheTransport(httpClient);Implement the interface that matches your execution model:
public class MyTransport implements HttpTransport {
private final MyHttpClient client;
public MyTransport(MyHttpClient client) {
this.client = client;
}
@Override
public RawResponse send(String method, URI uri, Map<String, String> headers,
String body, Duration timeout) {
// Adapt your client's API and return RawResponse
}
}All built-in transports include DEBUG-level logging via TransportLogger. See Logging for full details on both transport-level and application-level logging.
- Getting Started
- Sync Client
- Reactor Client
- Mutiny Client
- Retry & Backoff - transport decorator for automatic retry
- Design Principles