Skip to content

Refactor DefaultClient from constructor-based to Builder pattern for configurable HTTP client options#910

Open
utkrishtsahu wants to merge 1 commit intov4_developmentfrom
builder-pattern-default-client
Open

Refactor DefaultClient from constructor-based to Builder pattern for configurable HTTP client options#910
utkrishtsahu wants to merge 1 commit intov4_developmentfrom
builder-pattern-default-client

Conversation

@utkrishtsahu
Copy link
Contributor

@utkrishtsahu utkrishtsahu commented Feb 11, 2026

Changes

Added:

  • DefaultClient.Builder class — a new builder pattern API for constructing DefaultClient instances with full configuration control
  • connectTimeout(Int) — connection timeout in seconds (default: 10)
  • readTimeout(Int) — read timeout in seconds (default: 10)
  • writeTimeout(Int) — write timeout in seconds (default: 10)
  • callTimeout(Int) — overall call timeout in seconds (default: 0/disabled)
  • defaultHeaders(Map<String, String>) — headers included on every request
  • enableLogging(Boolean) — toggle HTTP logging
  • logLevel(HttpLoggingInterceptor.Level) — granular log level control
  • logger(HttpLoggingInterceptor.Logger) — custom logger implementation
  • addInterceptor(Interceptor) — add custom OkHttp interceptors
  • build() — creates the DefaultClient instance

Deprecated:

DefaultClient public constructor (DefaultClient(connectTimeout, readTimeout, defaultHeaders, enableLogging)) — deprecated with @deprecated annotation and ReplaceWith pointing to the Builder API. Still compiles and functions identically; IDE provides one-click quick-fix migration.

Usage:

val client = DefaultClient.Builder()
    .connectTimeout(30)
    .readTimeout(30)
    .writeTimeout(30)
    .enableLogging(true)
    .addInterceptor(myCustomInterceptor)
    .build()

account.networkingClient = client

References

SDK-7763

Testing

Build Passed
Unit Test Passed

Checklist

@utkrishtsahu utkrishtsahu requested a review from a team as a code owner February 11, 2026 10:32
private var callTimeout: Int = 0
private var defaultHeaders: Map<String, String> = mapOf()
private var enableLogging: Boolean = false
private var logLevel: HttpLoggingInterceptor.Level = HttpLoggingInterceptor.Level.BODY
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to provide the logLevel option. If the customer wants more control ,they can use a custom logging interceptor

private var enableLogging: Boolean = false
private var logLevel: HttpLoggingInterceptor.Level = HttpLoggingInterceptor.Level.BODY
private var logger: HttpLoggingInterceptor.Logger? = null
private val interceptors: MutableList<Interceptor> = mutableListOf()
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets not add option to configure interceptors . If there is a major request we can add this later .

* by calling this method multiple times. They are invoked in the order they were added,
* after the built-in [RetryInterceptor] and before the logging interceptor.
*/
public fun addInterceptor(interceptor: Interceptor): Builder =
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets not ad this option

* Only takes effect if [enableLogging] is set to `true`.
* Default is [HttpLoggingInterceptor.Level.BODY].
*/
public fun logLevel(level: HttpLoggingInterceptor.Level): Builder =
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets not add this option


okBuilder.addInterceptor(RetryInterceptor())

interceptors.forEach { okBuilder.addInterceptor(it) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove the custom interceptors for now

} else {
HttpLoggingInterceptor()
}
loggingInterceptor.setLevel(logLevel)
Copy link
Contributor

Choose a reason for hiding this comment

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

#763
Check the second approach suggested. We can follow that pattern

/**
* Internal constructor used by tests to inject SSL and Gson.
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
Copy link
Contributor

@pmathew92 pmathew92 Feb 12, 2026

Choose a reason for hiding this comment

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

Can't the tests use the builder now instead of this ?

.setLevel(HttpLoggingInterceptor.Level.BODY)
builder.addInterceptor(logger)
}
okHttpClient = okHttpClientBuilder.build()
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't this create a new client here ? Is this init block required now ?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants