Skip to content

Allow customization of underlying Netty HttpClient#737

Open
Periecle wants to merge 1 commit into
PlaytikaOSS:developfrom
Periecle:feature/custom-netty-httpclient-14969175955103701914
Open

Allow customization of underlying Netty HttpClient#737
Periecle wants to merge 1 commit into
PlaytikaOSS:developfrom
Periecle:feature/custom-netty-httpclient-14969175955103701914

Conversation

@Periecle
Copy link
Copy Markdown

@Periecle Periecle commented Feb 20, 2026

Implemented feature request #690 to allow customization of the underlying Netty HttpClient.
This is achieved by adding a clientCustomizer field (Function<HttpClient, HttpClient>) to WebReactiveOptions and applying it in NettyClientHttpConnectorBuilder.
Users can now provide a customizer via WebReactiveOptions.Builder to tweak the HttpClient configuration (e.g., DNS resolver, timeouts, etc.) beyond what was previously exposed.
Added integration test ClientCustomizerTest to verify that the customizer is applied correctly.

Summary by CodeRabbit

  • New Features

    • Added customization mechanism for Netty HTTP client to allow modification of client behavior and configuration
    • Clients can now register custom handlers for HTTP client setup
  • Tests

    • Added test demonstrating custom request header injection in HTTP requests

@Periecle Periecle added the enhancement New feature or request label Feb 20, 2026
@Periecle Periecle linked an issue Feb 20, 2026 that may be closed by this pull request
@Periecle
Copy link
Copy Markdown
Author

Periecle commented Mar 3, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

This PR introduces a pluggable customization mechanism for Netty HTTP clients in Feign Reactor. A new functional interface NettyHttpClientCustomizer is added, allowing users to register custom transformations on HttpClient instances. The customizer is threaded through the client builder chain—from the Spring configuration through WebReactiveFeign to the actual connector instantiation—and applied before connector creation. A test demonstrates header injection via customizer.

Changes

Cohort / File(s) Summary
Customizer Interface
feign-reactor-webclient/src/main/java/reactivefeign/webclient/NettyHttpClientCustomizer.java
New functional interface extending Function<HttpClient, HttpClient> to provide a pluggable hook for customizing Netty HttpClient instances.
Core Implementation
feign-reactor-webclient/src/main/java/reactivefeign/webclient/WebReactiveFeign.java, feign-reactor-webclient/src/main/java/reactivefeign/webclient/NettyClientHttpConnectorBuilder.java
Extended WebReactiveFeign.Builder with addCustomizer() method and collection field for storing customizers. Updated NettyClientHttpConnectorBuilder to accept and iterate over customizers, applying each to HttpClient before connector creation.
Spring Configuration
feign-reactor-spring-configuration/src/main/java/reactivefeign/spring/config/ReactiveFeignClientsConfiguration.java
Updated reactiveFeignBuilder() method signature to accept optional List<NettyHttpClientCustomizer> parameter and register each customizer on the builder instance.
Test Coverage
feign-reactor-webclient/src/test/java/reactivefeign/webclient/ClientCustomizerTest.java
New integration test demonstrating customizer functionality by injecting a custom X-Custom header via a Netty customizer, verifying the header is transmitted end-to-end.

Sequence Diagram(s)

sequenceDiagram
    participant User as User Code
    participant Config as ReactiveFeignClientsConfiguration
    participant Builder as WebReactiveFeign.Builder
    participant ConnBuilder as NettyClientHttpConnectorBuilder
    participant HttpClient as Netty HttpClient
    
    User->>Config: reactiveFeignBuilder(..., customizers)
    Config->>Builder: create builder
    Config->>Builder: addCustomizer() for each customizer
    Builder->>Builder: store customizers in list
    User->>Builder: build()
    Builder->>ConnBuilder: buildNettyClientHttpConnector(..., customizers)
    ConnBuilder->>HttpClient: create HttpClient
    ConnBuilder->>HttpClient: apply each customizer
    HttpClient-->>ConnBuilder: modified HttpClient
    ConnBuilder-->>Builder: ReactorClientHttpConnector
    Builder-->>User: WebReactiveFeign client ready
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With customizers now in place,
Netty clients fit each case,
Headers dance, transformations flow,
Through the builder's gentle show—
Feign hops free, no limits tight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Allow customization of underlying Netty HttpClient' accurately and concisely summarizes the main change in the pull request, which introduces a customization mechanism for the Netty HttpClient.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
feign-reactor-webclient/src/test/java/reactivefeign/webclient/ClientCustomizerTest.java (1)

17-23: Consider adding coverage for the Spring bean-injection path.

This test validates direct builder usage, but the PR also changes ReactiveFeignClientsConfiguration to inject List<NettyHttpClientCustomizer>. A focused test for that wiring would reduce regression risk.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feign-reactor-webclient/src/test/java/reactivefeign/webclient/ClientCustomizerTest.java`
around lines 17 - 23, Add a focused Spring context test that exercises the
bean-injection path for ReactiveFeignClientsConfiguration by loading the
application context (reuse ClientCustomizerTest/TestController and
`@SpringBootTest`) and defining a `@TestConfiguration` that declares a
NettyHttpClientCustomizer bean; in the test method autowire
List<NettyHttpClientCustomizer> (or the reactivefeign configuration class) and
assert the injected list contains the test bean to validate the new injection
wiring in ReactiveFeignClientsConfiguration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feign-reactor-webclient/src/main/java/reactivefeign/webclient/NettyClientHttpConnectorBuilder.java`:
- Around line 135-138: Guard against a customizer returning null by adding an
explicit null-check after calling NettyHttpClientCustomizer.apply in
NettyClientHttpConnectorBuilder; after each httpClient =
customizer.apply(httpClient) verify httpClient != null and if it is null throw a
clear IllegalStateException (or similar) that includes the customizer's
class/name and context (e.g., "NettyHttpClientCustomizer X returned null from
apply"), so connector construction fails fast with a useful message.

In
`@feign-reactor-webclient/src/main/java/reactivefeign/webclient/WebReactiveFeign.java`:
- Around line 72-75: In Builder<T>.addCustomizer(NettyHttpClientCustomizer
customizer) validate input and fail fast by checking if customizer is null and
throwing a clear exception (e.g., NullPointerException or
IllegalArgumentException) instead of accepting null into
nettyHttpClientCustomizers; update the method so it performs the null check
before adding to the nettyHttpClientCustomizers collection and returns this as
before to preserve fluent API semantics.

---

Nitpick comments:
In
`@feign-reactor-webclient/src/test/java/reactivefeign/webclient/ClientCustomizerTest.java`:
- Around line 17-23: Add a focused Spring context test that exercises the
bean-injection path for ReactiveFeignClientsConfiguration by loading the
application context (reuse ClientCustomizerTest/TestController and
`@SpringBootTest`) and defining a `@TestConfiguration` that declares a
NettyHttpClientCustomizer bean; in the test method autowire
List<NettyHttpClientCustomizer> (or the reactivefeign configuration class) and
assert the injected list contains the test bean to validate the new injection
wiring in ReactiveFeignClientsConfiguration.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 937e61c and 4fe8e5b.

📒 Files selected for processing (5)
  • feign-reactor-spring-configuration/src/main/java/reactivefeign/spring/config/ReactiveFeignClientsConfiguration.java
  • feign-reactor-webclient/src/main/java/reactivefeign/webclient/NettyClientHttpConnectorBuilder.java
  • feign-reactor-webclient/src/main/java/reactivefeign/webclient/NettyHttpClientCustomizer.java
  • feign-reactor-webclient/src/main/java/reactivefeign/webclient/WebReactiveFeign.java
  • feign-reactor-webclient/src/test/java/reactivefeign/webclient/ClientCustomizerTest.java

Comment on lines +135 to +138
if (customizers != null) {
for (NettyHttpClientCustomizer customizer : customizers) {
httpClient = customizer.apply(httpClient);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard against customizers returning null HttpClient.

A misbehaving customizer can return null and break connector construction with a non-obvious failure. Add an explicit null-check after apply.

Suggested fix
 if (customizers != null) {
     for (NettyHttpClientCustomizer customizer : customizers) {
-        httpClient = customizer.apply(httpClient);
+        httpClient = Objects.requireNonNull(
+                customizer.apply(httpClient),
+                "NettyHttpClientCustomizer must not return null HttpClient");
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (customizers != null) {
for (NettyHttpClientCustomizer customizer : customizers) {
httpClient = customizer.apply(httpClient);
}
if (customizers != null) {
for (NettyHttpClientCustomizer customizer : customizers) {
httpClient = Objects.requireNonNull(
customizer.apply(httpClient),
"NettyHttpClientCustomizer must not return null HttpClient");
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feign-reactor-webclient/src/main/java/reactivefeign/webclient/NettyClientHttpConnectorBuilder.java`
around lines 135 - 138, Guard against a customizer returning null by adding an
explicit null-check after calling NettyHttpClientCustomizer.apply in
NettyClientHttpConnectorBuilder; after each httpClient =
customizer.apply(httpClient) verify httpClient != null and if it is null throw a
clear IllegalStateException (or similar) that includes the customizer's
class/name and context (e.g., "NettyHttpClientCustomizer X returned null from
apply"), so connector construction fails fast with a useful message.

Comment on lines +72 to +75
public Builder<T> addCustomizer(NettyHttpClientCustomizer customizer){
this.nettyHttpClientCustomizers.add(customizer);
return this;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fail fast on null customizer input.

addCustomizer(null) is currently accepted and defers failure to connector creation time. Validate eagerly to keep error locality clear.

Suggested fix
 public Builder<T> addCustomizer(NettyHttpClientCustomizer customizer){
-    this.nettyHttpClientCustomizers.add(customizer);
+    this.nettyHttpClientCustomizers.add(
+            Objects.requireNonNull(customizer, "customizer must not be null"));
     return this;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public Builder<T> addCustomizer(NettyHttpClientCustomizer customizer){
this.nettyHttpClientCustomizers.add(customizer);
return this;
}
public Builder<T> addCustomizer(NettyHttpClientCustomizer customizer){
this.nettyHttpClientCustomizers.add(
Objects.requireNonNull(customizer, "customizer must not be null"));
return this;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feign-reactor-webclient/src/main/java/reactivefeign/webclient/WebReactiveFeign.java`
around lines 72 - 75, In Builder<T>.addCustomizer(NettyHttpClientCustomizer
customizer) validate input and fail fast by checking if customizer is null and
throwing a clear exception (e.g., NullPointerException or
IllegalArgumentException) instead of accepting null into
nettyHttpClientCustomizers; update the method so it performs the null check
before adding to the nettyHttpClientCustomizers collection and returns this as
before to preserve fluent API semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ability to configure underlying HttpClient in spring boot

1 participant