Import the BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-bom</artifactId>
<version>1.0.9-SNAPSHOT</version> <!-- ark-bom -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Add the modules you need:
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-core</artifactId>
</dependency>
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-jackson</artifactId>
</dependency>
<dependency>
<groupId>xyz.juandiii</groupId>
<artifactId>ark-transport-jdk</artifactId>
</dependency>Or use a starter:
| Starter | Stack | Features |
|---|---|---|
ark-spring-boot-starter |
Spring MVC (sync) | Config, TLS, retry, interceptors, headers, native |
ark-spring-boot-starter-webflux |
Spring WebFlux (reactive) | Config, TLS, interceptors, headers, native |
ark-quarkus-jackson |
Quarkus (sync + Mutiny) | Config, TLS, retry, interceptors, headers, native |
Ark client = ArkClient.builder()
.serializer(new JacksonSerializer(new ObjectMapper()))
.transport(new ArkJdkHttpTransport(HttpClient.newBuilder().build()))
.baseUrl("https://api.example.com")
.build();
User user = client.get("/users/1")
.retrieve()
.body(User.class);AsyncArk client = AsyncArkClient.builder()
.serializer(serializer)
.transport(new ArkJdkHttpTransport(HttpClient.newBuilder().build()))
.baseUrl("https://api.example.com")
.build();
CompletableFuture<User> user = client.get("/users/1")
.retrieve()
.body(User.class);ReactorArk client = ReactorArkClient.builder()
.serializer(serializer)
.transport(new ArkReactorNettyTransport(HttpClient.create()))
.baseUrl("https://api.example.com")
.build();
Mono<User> user = client.get("/users/1")
.retrieve()
.body(User.class);MutinyArk client = MutinyArkClient.builder()
.serializer(serializer)
.transport(new ArkVertxMutinyTransport(WebClient.create(vertx)))
.baseUrl("https://api.example.com")
.build();
Uni<User> user = client.get("/users/1")
.retrieve()
.body(User.class);VertxArk client = VertxArkClient.builder()
.serializer(serializer)
.transport(new ArkVertxFutureTransport(WebClient.create(vertx)))
.baseUrl("https://api.example.com")
.build();
Future<User> user = client.get("/users/1")
.retrieve()
.body(User.class);// Class<T> - simple types
User user = client.get("/users/1").retrieve().body(User.class);
String html = client.get("/health").retrieve().body(String.class);
// TypeRef<T> - generic types
List<User> users = client.get("/users").retrieve().body(new TypeRef<List<User>>() {});List<User> users = client.get("/users")
.queryParam("page", "1")
.queryParam("size", "20")
.retrieve()
.body(new TypeRef<List<User>>() {});User created = client.post("/users")
.contentType(MediaType.APPLICATION_JSON)
.body(new User("Juan", "juan@example.com"))
.retrieve()
.body(User.class);client.delete("/users/1").retrieve().toBodilessEntity();ArkResponse<User> response = client.get("/users/1")
.retrieve()
.toEntity(User.class);
int status = response.statusCode();
User body = response.body();
boolean ok = response.isSuccessful();User user = client.get("/slow-endpoint")
.timeout(Duration.ofSeconds(120))
.retrieve()
.body(User.class);HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.followRedirects(HttpClient.Redirect.NORMAL)
.sslContext(mySSLContext)
.build();
Ark client = ArkClient.builder()
.serializer(serializer)
.transport(new ArkJdkHttpTransport(httpClient))
.baseUrl("https://api.example.com")
.userAgent("MyApp", "2.0")
.requestInterceptor(request ->
request.header("X-Request-Id", UUID.randomUUID().toString()))
.responseInterceptor(response -> {
log.info("Status: {}", response.statusCode());
return response;
})
.build();ark.logging.level=BODYLevels: NONE, BASIC, HEADERS, BODY. See Logging for full details.
Define an interface - Ark creates the implementation:
@RegisterArkClient(configKey = "user-api", baseUrl = "${api.users.url}")
@Path("/users")
@Produces("application/json")
public interface UserApi {
@GET @Path("/{id}")
User getUser(@PathParam("id") String id);
}Configure per-client via application.properties:
ark.client.user-api.base-url=https://api.example.com
ark.client.user-api.http-version=HTTP_2See Declarative JAX-RS or Declarative Spring for full details.
User user = client.get("/users/1").retrieve().body(User.class);
CompletableFuture<User> cf = asyncClient.get("/users/1").retrieve().body(User.class);
Mono<User> mono = reactorClient.get("/users/1").retrieve().body(User.class);
Uni<User> uni = mutinyClient.get("/users/1").retrieve().body(User.class);
Future<User> future = vertxClient.get("/users/1").retrieve().body(User.class);- Sync Client
- Error Handling - typed exception hierarchy
- Reactor Client - Spring WebFlux
- Mutiny Client - Quarkus
- Transport Model - built-in and custom transports
- Serialization - Jackson, JSON-B, custom
- Logging - LoggingInterceptor + TransportLogger
- Retry & Backoff - automatic retry with exponential backoff
- Multipart Upload - file upload with
@RequestPart - Declarative JAX-RS -
@RegisterArkClientwith JAX-RS - Declarative Spring -
@RegisterArkClientwith@HttpExchange - Spring Boot Integration - auto-config, ArkProperties, TLS
- Quarkus Integration - @ConfigMapping, TLS
- Testing