Helidon WebClient is a comprehensive HTTP client library for Java microservices supporting HTTP/1.1, HTTP/2, and protocol negotiation with virtual thread support.
—
Access to protocol-specific functionality including HTTP/1.1 features like protocol upgrades, HTTP/2 specific capabilities, and non-HTTP protocols like WebSocket and gRPC.
Switch from the generic WebClient to protocol-specific clients for accessing advanced features.
/**
* Switch to a protocol-specific client using its configured settings
* @param protocol protocol instance, usually defined as a constant on the protocol interface
* @param <T> type of the protocol client
* @param <C> type of the protocol config
* @return a new protocol client instance
*/
<T, C extends ProtocolConfig> T client(Protocol<T, C> protocol);
/**
* Switch to a protocol-specific client with custom configuration
* @param protocol protocol instance, usually defined as a constant on the protocol interface
* @param protocolConfig configuration of the protocol to be used
* @param <T> type of the protocol client
* @param <C> type of the protocol config
* @return a new protocol client instance
*/
<T, C extends ProtocolConfig> T client(Protocol<T, C> protocol, C protocolConfig);Usage Examples:
import io.helidon.webclient.api.WebClient;
import io.helidon.webclient.http1.Http1Client;
import io.helidon.webclient.http2.Http2Client;
WebClient webClient = WebClient.create();
// Switch to HTTP/1.1 client
Http1Client http1Client = webClient.client(Http1Client.PROTOCOL);
// Switch to HTTP/2 client with custom config
Http2ClientProtocolConfig http2Config = Http2ClientProtocolConfig.builder()
.maxFrameSize(32768)
.build();
Http2Client http2Client = webClient.client(Http2Client.PROTOCOL, http2Config);HTTP/1.1 specific client with support for protocol upgrades and HTTP/1.1 features.
public interface Http1Client extends HttpClient<Http1ClientRequest> {
/**
* HTTP/1.1 protocol identifier
*/
String PROTOCOL_ID = "http/1.1";
/**
* Protocol instance for WebClient integration
*/
Protocol<Http1Client, Http1ClientProtocolConfig> PROTOCOL = ...;
/**
* Create HTTP/1.1 client with default configuration
* @return new HTTP/1.1 client
*/
static Http1Client create();
/**
* Create HTTP/1.1 client with custom configuration
* @param clientConfig configuration to use
* @return new HTTP/1.1 client
*/
static Http1Client create(Http1ClientConfig clientConfig);
/**
* Create HTTP/1.1 client with configuration customization
* @param consumer configuration consumer
* @return new HTTP/1.1 client
*/
static Http1Client create(Consumer<Http1ClientConfig.Builder> consumer);
/**
* Create configuration builder
* @return new configuration builder
*/
static Http1ClientConfig.Builder builder();
}
public interface Http1ClientRequest extends ClientRequest<Http1ClientRequest> {
/**
* Submit request with entity (overridden for return type)
* @param entity request entity
* @return HTTP/1.1 response
*/
Http1ClientResponse submit(Object entity);
/**
* Execute request without entity (overridden for return type)
* @return HTTP/1.1 response
*/
default Http1ClientResponse request();
/**
* Handle output stream for request body (overridden for return type)
* @param outputStreamConsumer consumer to write to output stream
* @return HTTP/1.1 response
*/
Http1ClientResponse outputStream(OutputStreamHandler outputStreamConsumer);
/**
* Upgrade to different protocol (WebSocket, HTTP/2, etc.)
* @param protocol target protocol identifier
* @return upgrade response
*/
UpgradeResponse upgrade(String protocol);
}
public interface Http1ClientResponse extends HttpClientResponse {
// HTTP/1.1 specific response features
}Usage Examples:
import io.helidon.webclient.http1.Http1Client;
import io.helidon.webclient.http1.Http1ClientRequest;
import io.helidon.webclient.http1.Http1ClientResponse;
// Create standalone HTTP/1.1 client
Http1Client http1Client = Http1Client.create();
// Or get from WebClient
WebClient webClient = WebClient.create();
Http1Client http1Client = webClient.client(Http1Client.PROTOCOL);
// Make HTTP/1.1 request
Http1ClientResponse response = http1Client.get("/api/data").request();
// Protocol upgrade (e.g., to WebSocket)
Http1ClientRequest upgradeRequest = http1Client.get("/websocket")
.header(HeaderNames.CONNECTION, "Upgrade")
.header(HeaderNames.UPGRADE, "websocket");
UpgradeResponse upgradeResponse = upgradeRequest.upgrade("websocket");HTTP/2 specific client with support for HTTP/2 features like multiplexing and server push.
public interface Http2Client extends HttpClient<Http2ClientRequest> {
/**
* HTTP/2 protocol identifier
*/
String PROTOCOL_ID = "h2";
/**
* Protocol instance for WebClient integration
*/
Protocol<Http2Client, Http2ClientProtocolConfig> PROTOCOL = ...;
/**
* Create HTTP/2 client with default configuration
* @return new HTTP/2 client
*/
static Http2Client create();
/**
* Create HTTP/2 client with custom configuration
* @param clientConfig configuration to use
* @return new HTTP/2 client
*/
static Http2Client create(Http2ClientConfig clientConfig);
/**
* Create HTTP/2 client with configuration customization
* @param consumer configuration consumer
* @return new HTTP/2 client
*/
static Http2Client create(Consumer<Http2ClientConfig.Builder> consumer);
/**
* Create configuration builder
* @return new configuration builder
*/
static Http2ClientConfig.Builder builder();
}
public interface Http2ClientRequest extends ClientRequest<Http2ClientRequest> {
/**
* Submit request with entity (overridden for return type)
* @param entity request entity
* @return HTTP/2 response
*/
Http2ClientResponse submit(Object entity);
/**
* Execute request without entity (overridden for return type)
* @return HTTP/2 response
*/
default Http2ClientResponse request();
/**
* Handle output stream for request body (overridden for return type)
* @param outputStreamConsumer consumer to write to output stream
* @return HTTP/2 response
*/
Http2ClientResponse outputStream(OutputStreamHandler outputStreamConsumer);
}
public interface Http2ClientResponse extends HttpClientResponse {
// HTTP/2 specific response features
}Usage Examples:
import io.helidon.webclient.http2.Http2Client;
import io.helidon.webclient.http2.Http2ClientProtocolConfig;
// Create HTTP/2 client with custom configuration
Http2Client http2Client = Http2Client.create(builder -> builder
.maxFrameSize(32768)
.enablePush(true));
// Or get from WebClient with configuration
WebClient webClient = WebClient.create();
Http2ClientProtocolConfig http2Config = Http2ClientProtocolConfig.builder()
.maxFrameSize(65536)
.build();
Http2Client http2Client = webClient.client(Http2Client.PROTOCOL, http2Config);
// Make HTTP/2 request
Http2ClientResponse response = http2Client.get("/api/data").request();WebSocket client for real-time communication over WebSocket protocol.
public interface WsClient {
/**
* WebSocket protocol identifier
*/
String PROTOCOL_ID = "websocket";
/**
* Protocol instance for WebClient integration
*/
Protocol<WsClient, WsClientProtocolConfig> PROTOCOL = ...;
/**
* Create WebSocket client
* @return new WebSocket client
*/
static WsClient create();
/**
* Create WebSocket client with configuration
* @param config WebSocket configuration
* @return new WebSocket client
*/
static WsClient create(WsClientConfig config);
}Usage Examples:
import io.helidon.webclient.websocket.WsClient;
// Get WebSocket client from WebClient
WebClient webClient = WebClient.create();
WsClient wsClient = webClient.client(WsClient.PROTOCOL);
// Connect to WebSocket endpoint
wsClient.connect("/websocket", (session, message) -> {
// Handle WebSocket messages
});gRPC client for Protocol Buffers-based RPC communication over HTTP/2.
public interface GrpcClient {
/**
* gRPC protocol identifier
*/
String PROTOCOL_ID = "grpc";
/**
* Protocol instance for WebClient integration
*/
Protocol<GrpcClient, GrpcClientProtocolConfig> PROTOCOL = ...;
/**
* Create gRPC client
* @return new gRPC client
*/
static GrpcClient create();
/**
* Create gRPC client with configuration
* @param config gRPC configuration
* @return new gRPC client
*/
static GrpcClient create(GrpcClientConfig config);
}Usage Examples:
import io.helidon.webclient.grpc.GrpcClient;
// Get gRPC client from WebClient
WebClient webClient = WebClient.create();
GrpcClient grpcClient = webClient.client(GrpcClient.PROTOCOL);
// Make gRPC call (assumes generated stub classes)
GreeterServiceStub stub = GreeterServiceStub.create(grpcClient);
HelloReply response = stub.sayHello(HelloRequest.newBuilder()
.setName("World")
.build());Configure protocol-specific settings for different HTTP versions and protocols.
public interface ProtocolConfig {
// Base protocol configuration
}
public interface Http1ClientProtocolConfig extends ProtocolConfig {
// HTTP/1.1 specific configuration
boolean keepAlive();
boolean pipelining();
Duration keepAliveTimeout();
}
public interface Http2ClientProtocolConfig extends ProtocolConfig {
// HTTP/2 specific configuration
int maxFrameSize();
int maxConcurrentStreams();
boolean enablePush();
Duration connectionWindowSize();
Duration streamWindowSize();
}
public interface WsClientProtocolConfig extends ProtocolConfig {
// WebSocket specific configuration
List<String> subProtocols();
Duration pingPeriod();
int maxMessageSize();
}
public interface GrpcClientProtocolConfig extends ProtocolConfig {
// gRPC specific configuration
Duration deadline();
Metadata headers();
CallCredentials credentials();
}Helidon WebClient automatically discovers available HTTP protocol implementations based on classpath and server capabilities.
Protocol Negotiation Process:
Usage Examples:
// WebClient automatically selects appropriate protocol
WebClient client = WebClient.builder()
// Prefer HTTP/2, fall back to HTTP/1.1
.addProtocolPreference(List.of("h2", "http/1.1"))
.build();
// Request will use best available protocol
String response = client.get("https://example.com/api/data")
.requestEntity(String.class);
// Force specific protocol if needed
String response = client.get("https://example.com/api/data")
.protocolId("http/1.1") // Force HTTP/1.1
.requestEntity(String.class);public interface Protocol<T, C extends ProtocolConfig> {
ClientProtocolProvider<T, C> provider();
}
public interface ProtocolConfig {
// Base protocol configuration marker interface
}
public interface ClientProtocolProvider<T, C extends ProtocolConfig> {
T protocol(WebClient client, C protocolConfig);
}
public interface UpgradeResponse {
Status status();
ClientResponseHeaders headers();
// Protocol-specific upgrade result
}
// HTTP/1.1 specific types
public interface Http1Client extends HttpClient<Http1ClientRequest> {
// HTTP/1.1 client interface
}
public interface Http1ClientRequest extends ClientRequest<Http1ClientRequest> {
Http1ClientResponse submit(Object entity);
Http1ClientResponse request();
Http1ClientResponse outputStream(OutputStreamHandler outputStreamConsumer);
UpgradeResponse upgrade(String protocol);
}
public interface Http1ClientResponse extends HttpClientResponse {
// HTTP/1.1 response interface
}
// HTTP/2 specific types
public interface Http2Client extends HttpClient<Http2ClientRequest> {
// HTTP/2 client interface
}
public interface Http2ClientRequest extends ClientRequest<Http2ClientRequest> {
Http2ClientResponse submit(Object entity);
Http2ClientResponse request();
Http2ClientResponse outputStream(OutputStreamHandler outputStreamConsumer);
}
public interface Http2ClientResponse extends HttpClientResponse {
// HTTP/2 response interface
}Install with Tessl CLI
npx tessl i tessl/maven-io-helidon-webclient--helidon-webclient