Summary
Revisit how much transport-level configuration the SDK exposes versus delegating to the underlying HTTP client. Today both reference transports offer two construction paths:
create(client) — BYO, fully-configured OkHttpClient / java.net.http.HttpClient, used verbatim.builder() — an SDK-managed subset: connect/read/write/call timeouts, proxy (ProxyOptions), and followRedirects.
For now we are keeping every option we currently support. This issue tracks the deferred decision about trimming that surface.
Motivation
This is a service-style SDK (users talk to a specific API, à la the AWS SDK), not a general-purpose HTTP client. That shapes which knobs are worth owning:
- Service-behavior settings (retry policy, redirect handling, auth to the service, endpoints, default timeouts) are the SDK author's call and should not be re-exposed as user knobs, or only minimally. Re-exposing pass-through transport config the SDK never consumes is a leaky surface that drifts from what the underlying client actually honors.
- User-environment settings (proxy, TLS trust, possibly a timeout override) belong to the user. Since the typical service-SDK user calls
Client.create() and does not construct their own HTTP client, these need a first-class, simple path — pushing them onto the BYO-client path would force the common "behind a corporate proxy" case through the power-user escape hatch.
Open questions to resolve later
Timeout knobs on builder(). Connect/read/write/call timeouts are pure pass-through to the underlying client and differ per transport (OkHttp has callTimeout/writeTimeout; java.net.http does not). Candidate for removal in favor of BYO + sensible service defaults. Decide whether any timeout override stays as a first-class knob.
Correctness-critical flags under BYO.followRedirects(false) and retryOnConnectionFailure(false) are SDK invariants (the pipeline owns redirects via DefaultRedirectStep and retries via DefaultRetryStep). A verbatim BYO client can silently re-enable both, causing double redirect/retry handling and tripping a non-replayable body's consume-guard. Decide between:
- derive-and-enforce:
client.newBuilder().followRedirects(false).followSslRedirects(false).retryOnConnectionFailure(false).build() on create() (keeps all user config, shares the pool so close() stays a no-op for BYO); or - document-and-trust: leave it to the caller (a silent footgun).
ProxyOptions scope. Keep the proxy concept at the SDK level (it is the user's environment, not the API owner's, and users are not holding a client to set it on), but reconsider the parts that are not pulling their weight:
challengeHandler is currently ignored by every transport (logs a warning and falls back to Basic) — remove or implement.Type.SOCKS4 / Type.SOCKS5 are only reachable via the direct constructor; fromConfiguration only ever produces Type.HTTP. Confirm whether SOCKS support is exercised.- Confirm the env-var bridge (
HTTP_PROXY / HTTPS_PROXY / NO_PROXY) is the load-bearing value, since ProxySelector.getDefault() already covers system properties for OkHttp. Consider wiring ProxySelector.getDefault() into the JDK transport for system-property parity.
Notes
Any change here that alters a public signature requires ./gradlew apiDump and committing the regenerated .api snapshots. Removing ProxyOptions or builder methods is a breaking change for current alpha consumers.
Summary
Revisit how much transport-level configuration the SDK exposes versus delegating to the underlying HTTP client. Today both reference transports offer two construction paths:
create(client)— BYO, fully-configuredOkHttpClient/java.net.http.HttpClient, used verbatim.builder()— an SDK-managed subset: connect/read/write/call timeouts, proxy (ProxyOptions), andfollowRedirects.For now we are keeping every option we currently support. This issue tracks the deferred decision about trimming that surface.
Motivation
This is a service-style SDK (users talk to a specific API, à la the AWS SDK), not a general-purpose HTTP client. That shapes which knobs are worth owning:
Client.create()and does not construct their own HTTP client, these need a first-class, simple path — pushing them onto the BYO-client path would force the common "behind a corporate proxy" case through the power-user escape hatch.Open questions to resolve later
Timeout knobs on
builder(). Connect/read/write/call timeouts are pure pass-through to the underlying client and differ per transport (OkHttp hascallTimeout/writeTimeout;java.net.httpdoes not). Candidate for removal in favor of BYO + sensible service defaults. Decide whether any timeout override stays as a first-class knob.Correctness-critical flags under BYO.
followRedirects(false)andretryOnConnectionFailure(false)are SDK invariants (the pipeline owns redirects viaDefaultRedirectStepand retries viaDefaultRetryStep). A verbatim BYO client can silently re-enable both, causing double redirect/retry handling and tripping a non-replayable body's consume-guard. Decide between:client.newBuilder().followRedirects(false).followSslRedirects(false).retryOnConnectionFailure(false).build()oncreate()(keeps all user config, shares the pool soclose()stays a no-op for BYO); orProxyOptionsscope. Keep the proxy concept at the SDK level (it is the user's environment, not the API owner's, and users are not holding a client to set it on), but reconsider the parts that are not pulling their weight:challengeHandleris currently ignored by every transport (logs a warning and falls back to Basic) — remove or implement.Type.SOCKS4/Type.SOCKS5are only reachable via the direct constructor;fromConfigurationonly ever producesType.HTTP. Confirm whether SOCKS support is exercised.HTTP_PROXY/HTTPS_PROXY/NO_PROXY) is the load-bearing value, sinceProxySelector.getDefault()already covers system properties for OkHttp. Consider wiringProxySelector.getDefault()into the JDK transport for system-property parity.Notes
Any change here that alters a public signature requires
./gradlew apiDumpand committing the regenerated.apisnapshots. RemovingProxyOptionsor builder methods is a breaking change for current alpha consumers.