REST clients
View Markdownvertique-rest-client is Vertique’s declarative outbound HTTP client. It uses familiar JAX-RS
annotations on a Java interface, but it is not jakarta.ws.rs.client and does not implement a
JAX-RS client container. Each invocation becomes an asynchronous HTTP request over Vert.x
WebClient and returns a Future result.
Use this page when your application calls a known HTTP service. Use REST APIs for inbound JAX-RS resources, and JAX-RS compatibility for the server-side compatibility boundary.
By the end of this page you will have a typed client interface, know how to build or inject its proxy, and understand where outbound resilience and configuration are resolved.
Define the client interface
Section titled “Define the client interface”Annotate one Java interface per upstream service. @RestClient gives the client a logical name and
an optional default base URL. JAX-RS annotations describe the HTTP operation and its parameters.
Methods return a Future result so the call stays asynchronous.
This excerpt is from the public
UserClient.java
example. The interface-level circuit breaker applies to all of its methods unless a method
overrides it:
@RestClient(name = "userService", value = "http://localhost:8081")@Path("/api/users")@Produces("application/json")@Consumes("application/json")@CircuitBreaker(maxFailures = 5, timeoutMs = 5000)public interface UserClient {
@GET Future<List<User>> list(@QueryParam("page") int page);
@GET @Path("/{id}") Future<Optional<User>> findById(@PathParam("id") String id);
@POST @ExpectedStatus(201) Future<User> create(User user);
@DELETE @Path("/{id}") @ExpectedStatus(204) Future<Void> delete(@PathParam("id") String id);}The client name is also the key used for external configuration. Method annotations override interface defaults where the client supports both levels. The client shares Vertique’s parameter conversion and JSON serialization infrastructure with the server runtime, but the request dispatch, connection pool, and lifecycle are client-specific.
Build or inject the client
Section titled “Build or inject the client”For a standalone client, create a builder, set the base URL and transport defaults, and build the
typed proxy. This is the canonical builder shape from the
vertique-rest-client module reference:
UserClient client = RestClientBuilder.create(vertx) .baseUrl("http://user-service:8080") .readTimeout(5, TimeUnit.SECONDS) .build(UserClient.class);The builder scans and validates the interface, resolves converters and JSON configuration, creates
the client context, and returns the proxy during build(). A missing base URL, an unsupported
parameter converter, or an unknown configured profile fails during build(), before the first
call.
In a Dagger application, add RestClientModule and the generated
GeneratedRestClientsModule to the component. The generated module contributes the binding for
each @RestClient interface, while RestClientModule provides the factory and shared client
infrastructure. The public example’s
AppComponent
shows the complete composition.
Add outbound resilience
Section titled “Add outbound resilience”The declarative client owns the outbound call boundary, so inline resilience annotations
activate directly on the client interface or method. Use @Timeout, @Retry, @CircuitBreaker,
or @Bulkhead at interface level for a default shared by its methods, or at method level for a
method-specific override. Unlike a concrete resource or service bean, a client interface does not
need @Resilient for inline declarations.
Use @Resilient(policy = "payments") on a client method when a Dagger-managed client should select
a named policy tier. Install ResiliencePoliciesModule so the named tier is available. The
client-level restClient.{name}.retry configuration is a higher-precedence transport override.
Standalone builders have no named-policy registry. An unknown named policy fails while the client
is built.
The runtime creates one resilience pipeline per client method. A retry is a new physical HTTP attempt, while a bulkhead permit covers the complete logical call, including its retries. Keep retry declarations for operations that are replay-safe or idempotent. A resource boundary should normally enforce only the bounded timeout described in REST APIs.
Configure endpoint and transport behavior
Section titled “Configure endpoint and transport behavior”External configuration is read from the restClient section. The client name comes from
@RestClient(name = "..."), or from the interface’s simple name when name is blank.
Configuration keys include:
restClient.{name}.baseUrl: overrides the annotation and builder base URL.restClient.{name}.readTimeoutMs: per-request timeout in milliseconds.restClient.{name}.retry.maxRetriesandbackoffStrategy: client-level retry overrides.restClient.{name}.circuitBreaker.*: circuit-breaker settings.restClient.{name}.webClient.*andpool.*: transport and connection-pool settings.restClient.defaults.jsonProfile: a boundary-wide JSON mapper profile default.
External configuration has the highest priority. Method annotations then override interface
defaults, followed by builder settings and framework defaults. Duration keys in the external
configuration use explicit units, such as readTimeoutMs. Do not copy raw Vert.x duration names
into the application configuration. The complete key table and precedence matrix are in the
vertique-rest-client module reference.
Manage lifecycle and failures
Section titled “Manage lifecycle and failures”Standalone builders own the resilience runtime they create and should be closed when the client
lifetime ends. Builders created with an application-supplied runtime, and builders returned by
RestClientFactory, do not own that application runtime. Closing them releases only their client
contexts and WebClient instances. close() is deterministic and idempotent.
Client configuration and interface metadata are resolved at build time. Transport failures,
unexpected status responses, conversion errors, and resilience rejections propagate through the
REST-client failure hierarchy. They do not become inbound JAX-RS Response objects automatically.
Choose an application-level error policy at the call site or in a client interceptor.
Learn more
Section titled “Learn more”vertique-rest-clientmodule reference: complete annotations, request pipeline, configuration, failure hierarchy, and lifecycle.- Configuration: define a named resilience policy tier for Dagger-managed clients.
- JAX-RS compatibility: why this client is separate from
jakarta.ws.rs.clientcompatibility. - REST APIs: define inbound JAX-RS resources and bound their request-side work.
- Services: use generated event-bus-backed clients for internal service contracts.
Continue reading
Section titled “Continue reading”- Previous: REST APIs
- Next: JAX-RS compatibility