Skip to content

Reconsider transport-config surface: delegate pass-through settings to the underlying client #159

@OmarAlJarrah

Description

@OmarAlJarrah

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

  1. 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.

  2. 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).
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    sdk-coresdk-core toolkittech-debtsimplification / cleanup

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions