The AsyncArk client returns CompletableFuture<T> - non-blocking execution using Java's built-in async primitives.
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-async</artifactId>
</dependency>
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-jdk</artifactId>
</dependency>AsyncArk client = AsyncArkClient.builder()
.serializer(new JacksonSerializer(new ObjectMapper()))
.transport(new ArkJdkHttpTransport(HttpClient.newBuilder().build()))
.baseUrl("https://api.example.com")
.build();ArkJdkHttpTransport supports both sync and async execution by implementing both HttpTransport and AsyncHttpTransport.
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.sslContext(sslContext)
.executor(Executors.newVirtualThreadPerTaskExecutor())
.build();
ArkJdkHttpTransport transport = new ArkJdkHttpTransport(httpClient);CompletableFuture<User> user = client.get("/users/1")
.retrieve()
.body(User.class);CompletableFuture<User> created = client.post("/users")
.contentType(MediaType.APPLICATION_JSON)
.body(new User("Juan", "juan@example.com"))
.retrieve()
.body(User.class);CompletableFuture<ArkResponse<User>> response = client.get("/users/1")
.retrieve()
.toEntity(User.class);
response.thenAccept(r -> {
int status = r.statusCode();
User body = r.body();
});CompletableFuture<User> user = client.get("/slow-endpoint")
.timeout(Duration.ofSeconds(60))
.retrieve()
.body(User.class);See Error Handling for the full exception hierarchy. Errors propagate through the CompletableFuture:
client.get("/users/1")
.retrieve()
.body(User.class)
.exceptionally(ex -> {
if (ex.getCause() instanceof NotFoundException) {
return User.unknown();
}
throw new CompletionException(ex);
});