Enhanced HttpClient¶
Methanol has a special HttpClient
that extends the standard one with interesting features.
Unsurprisingly, the client is named Methanol
.
Usage¶
In addition to interceptors and caching, Methanol
can apply default properties to your requests.
Think resolving with a base URI, adding default request headers, default timeouts, etc.
var builder = Methanol.newBuilder()
.userAgent("Will Smith") // Custom User-Agent
.baseUri("https://api.github.com") // Base URI to resolve requests' URI against
.defaultHeader("Accept","application/json") // Default request headers
.requestTimeout(Duration.ofSeconds(20)) // Default request timeout
.headersTimeout(Duration.ofSeconds(5)) // Timeout for receiving response headers
.readTimeout(Duration.ofSeconds(5)) // Timeout for single reads
.autoAcceptEncoding(true); // Transparent response compression, this is true by default
// Continue using as a standard HttpClient.Builder.
var client = builder.connectTimeout(Duration.ofSeconds(30)).build();
You can also build from an existing HttpClient
instance. However, you can't install an HttpCache
in such case.
var prebuiltClient = HttpClient.newHttpClient();
var client = Methanol.newBuilder(prebuiltClient).build();
Note
Default properties don't override those the request already has. For instance, a client with a
default Accept: text/html
will not override a request's Accept: application/json
.
Transparent Compression¶
If autoAcceptEncoding
is enabled, the client complements requests with an Accept-Encoding
header
which accepts all supported encodings (i.e. available BodyDecoder
providers).
Additionally, the response is transparently decompressed.
Since deflate
& gzip
are supported out of the box, they're always included in Accept-Encoding
.
For instance, if brotli is installed, requests will typically have:
Accept-Encoding: gzip, deflate, br
.
If you want specific encodings to be applied, add Accept-Encoding
as a default header or
explicitly set one in your request.
// Advertise brotli decompression
var client = Methanol.newBuilder()
.defaultHeader("Accept-Encoding", "br")
.build();
// Advertise brotli decompression
var request = MutableRequest.GET(uri)
.header("Accept-Encoding", "br");
MimeBodyPublisher¶
Methanol
automatically sets a request's Content-Type
if it has a MimeBodyPublisher
.
If the request already has a Content-Type
, it's overwritten. This makes sense as a body knows its
media type better than the containing request.
Reactive Dispatching¶
If you like reactive streams, use Methanol::exchange
, which is like sendAsync
but returns
Publisher<HttpResponse<T>>
sources instead.
var client = Methanol.create();
var request = MutableRequest.GET("https://http2-push.appspot.com/?nopush");
var publisher = client.exchange(request, BodyHandlers.ofFile(Path.of("page.html")));
JdkFlowAdapter.flowPublisherToFlux(publisher)
.doOnNext(response -> System.out.printf("%s: %s", response, response.body()))
.blockLast();
var client = Methanol.create();
var request = MutableRequest.GET("https://http2-push.appspot.com");
var publisher = client.exchange(
request,
BodyHandlers.ofFile(Path.of("page.html")),
pushPromise -> BodyHandlers.ofFile(Path.of(pushPromise.uri().getPath()).getFileName()));
JdkFlowAdapter.flowPublisherToFlux(publisher)
.doOnNext(response -> System.out.printf("%s: %s%n", response, response.body()))
.blockLast();
MutableRequest¶
MutableRequest
is an HttpRequest
with additional properties. It implements HttpRequest.Builder
for settings request's fields.
var response = client.send(
MutableReqeust.GET(uri).header("Accept", "application/json"),
BodyHandlers.ofString());
MutableRequest
accepts relative URIs (standard HttpRequest.Builder
doesn't).
This complements Methanol
's base URIs, against which relative ones are resolved.
Tip
Use MutableRequest::toImmutableRequest
to get an immutable HttpRequest
snapshot.