Skip to content

Commit

Permalink
Allow more fine-grained control of compression setting for REST Client
Browse files Browse the repository at this point in the history
  • Loading branch information
geoand committed Feb 21, 2025
1 parent e701f48 commit eccb08d
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 14 deletions.
15 changes: 14 additions & 1 deletion docs/src/main/asciidoc/rest-client.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1755,9 +1755,22 @@ The code uses the following pieces:
As previously mentioned, the body parameter needs to be properly crafted by the application code to conform to the service's requirements.

=== Receiving compressed messages
REST Client also supports receiving compressed messages using GZIP. You can enable the HTTP compression support by adding the property `quarkus.http.enable-compression=true`.
REST Client also supports receiving compressed messages using GZIP and can be enabled via configuration.
When this feature is enabled and a server returns a response that includes the header `Content-Encoding: gzip`, REST Client will automatically decode the content and proceed with the message handling.

An example configuration could be:

[source,properties]
----
# global configuration is used for all clients
quarkus.rest-client.enable-compression=true
# per-client configuration overrides the global settings for a specific client
quarkus.rest-client.my-client.enable-compression=true
----

The REST Client falls back onto the Quarkus wide `quarkus.http.enable-compression` configuration property (which defaults to `false`) if no REST Client specific property is set.

== Proxy support
REST Client supports sending requests through a proxy.
It honors the JVM settings for it but also allows to specify both:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,17 @@ public interface RestClientsConfig {
@ConfigDocDefault("8k")
Optional<MemorySize> maxChunkSize();

/**
* Supports receiving compressed messages using GZIP.
* When this feature is enabled and a server returns a response that includes the header {@code Content-Encoding: gzip},
* REST Client will automatically decode the content and proceed with the message handling.
* <p>
* This property is not applicable to the RESTEasy Client.
* <p>
* Can be overwritten by client-specific settings.
*/
Optional<Boolean> enableCompression();

/**
* If the Application-Layer Protocol Negotiation is enabled, the client will negotiate which protocol to use over the
* protocols exposed by the server. By default, it will try to use HTTP/2 first and if it's not enabled, it will
Expand Down Expand Up @@ -600,6 +611,15 @@ default Optional<String> uriReload() {
@ConfigDocDefault("8K")
Optional<MemorySize> maxChunkSize();

/**
* Supports receiving compressed messages using GZIP.
* When this feature is enabled and a server returns a response that includes the header {@code Content-Encoding: gzip},
* REST Client will automatically decode the content and proceed with the message handling.
* <p>
* This property is not applicable to the RESTEasy Client.
*/
Optional<Boolean> enableCompression();

/**
* If the Application-Layer Protocol Negotiation is enabled, the client will negotiate which protocol to use over the
* protocols exposed by the server. By default, it will try to use HTTP/2 first and if it's not enabled, it will
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.vertx.http.Compressed;

public class ClientUsingGzipCompressionTest {
public class ClientUsingGzipCompressionGlobalSettingTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(MyResource.class, Message.class, MyClient.class))
.withConfigurationResource("client-using-gzip-application.properties");
.overrideConfigKey("quarkus.http.enable-compression", "true")
.overrideRuntimeConfigKey("quarkus.rest-client.my-client.url", "http://localhost:${quarkus.http.test-port:8081}");

@RestClient
MyClient client;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@ static QuarkusRestClientBuilder newBuilder() {
*/
QuarkusRestClientBuilder disableDefaultMapper(Boolean disable);

/**
* Supports receiving compressed messages using GZIP.
* When this feature is enabled and a server returns a response that includes the header {@code Content-Encoding: gzip},
* REST Client will automatically decode the content and proceed with the message handling.
*/
QuarkusRestClientBuilder enableCompression(boolean enableCompression);

/**
* Based on the configured QuarkusRestClientBuilder, creates a new instance of the given REST interface to invoke API calls
* against.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ public QuarkusRestClientBuilder disableDefaultMapper(Boolean disable) {
return this;
}

@Override
public QuarkusRestClientBuilder enableCompression(boolean enableCompression) {
proxy.enableCompression(enableCompression);
return this;
}

@Override
public <T> T build(Class<T> clazz) throws IllegalStateException, RestClientDefinitionException {
return proxy.build(clazz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public class RestClientBuilderImpl implements RestClientBuilder {
private Boolean trustAll;
private String userAgent;
private Boolean disableDefaultMapper;
private Boolean enableCompression;

@Override
public RestClientBuilderImpl baseUrl(URL url) {
Expand Down Expand Up @@ -266,6 +267,11 @@ public RestClientBuilderImpl disableDefaultMapper(Boolean disableDefaultMapper)
return this;
}

public RestClientBuilderImpl enableCompression(boolean enableCompression) {
this.enableCompression = enableCompression;
return this;
}

@Override
public RestClientBuilderImpl executorService(ExecutorService executor) {
throw new IllegalArgumentException("Specifying executor service is not supported. " +
Expand Down Expand Up @@ -533,10 +539,20 @@ public <T> T build(Class<T> aClass) throws IllegalStateException, RestClientDefi
clientBuilder.alpn(restClients.alpn().get());
}

Boolean enableCompression = ConfigProvider.getConfig()
.getOptionalValue(ENABLE_COMPRESSION, Boolean.class).orElse(false);
if (enableCompression) {
clientBuilder.enableCompression();
Boolean effectiveEnableCompression = enableCompression;
if (effectiveEnableCompression == null) {
if (restClients.enableCompression().isPresent()) {
effectiveEnableCompression = restClients.enableCompression().get();
}
}
if (effectiveEnableCompression == null) {
var maybeGlobalEnableCompression = ConfigProvider.getConfig().getOptionalValue(ENABLE_COMPRESSION, Boolean.class);
if (maybeGlobalEnableCompression.isPresent()) {
effectiveEnableCompression = maybeGlobalEnableCompression.get();
}
}
if (effectiveEnableCompression != null) {
clientBuilder.enableCompression(effectiveEnableCompression);
}

if (proxyHost != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ private void configureCustomProperties(QuarkusRestClientBuilder builder) {
configRoot.multipart().maxChunkSize());
builder.property(QuarkusRestClientProperties.MAX_CHUNK_SIZE, maxChunkSize.orElse(DEFAULT_MAX_CHUNK_SIZE));

Optional<Boolean> enableCompressions = oneOf(restClientConfig.enableCompression(), configRoot.enableCompression());
if (enableCompressions.isPresent()) {
builder.enableCompression(enableCompressions.get());
}

Boolean http2 = oneOf(restClientConfig.http2()).orElse(configRoot.http2());
builder.property(QuarkusRestClientProperties.HTTP2, http2);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public class ClientBuilderImpl extends ClientBuilder {
private ClientLogger clientLogger = new DefaultClientLogger();
private String userAgent = RestClientRequestContext.DEFAULT_USER_AGENT_VALUE;

private boolean enableCompression;
private Boolean enableCompression;

public ClientBuilderImpl() {
configuration = new ConfigurationImpl(RuntimeType.CLIENT);
Expand Down Expand Up @@ -202,8 +202,8 @@ public ClientBuilder clientLogger(ClientLogger clientLogger) {
return this;
}

public ClientBuilder enableCompression() {
this.enableCompression = true;
public ClientBuilder enableCompression(boolean enableCompression) {
this.enableCompression = enableCompression;
return this;
}

Expand Down Expand Up @@ -278,7 +278,7 @@ public ClientImpl build() {
}
}

if (enableCompression) {
if (Boolean.TRUE.equals(enableCompression)) {
configuration.register(ClientGZIPDecodingInterceptor.class);
}

Expand Down

0 comments on commit eccb08d

Please sign in to comment.