Skip to content

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

Merged
utkrishtsahu merged 3 commits intov4_developmentfrom
builder-pattern-default-client
Feb 16, 2026
Merged

Refactor DefaultClient from constructor-based to Builder pattern for configurable HTTP client options#910
utkrishtsahu merged 3 commits 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

#787 #763

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

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 .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

* 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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

* 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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed


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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

} 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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to follow approach 2.The Builder now accepts an HttpLoggingInterceptor.Logger via .logger(myLogger)

/**
* 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 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the @VisibleForTesting internal constructor(...) entirely.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleaned up. The init block now just calls okHttpClientBuilder.build() and creates the nonRetryableOkHttpClient from it. No duplicate configuration

EXAMPLES.md Outdated

### Logging configuration
<details>
<summary>Legacy constructor (still supported)</summary>
Copy link
Contributor

@pmathew92 pmathew92 Feb 16, 2026

Choose a reason for hiding this comment

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

This should be termed as Deprecated instead of still supported.
Better , I think we shouldn't show the legacy one at all and show only the builder pattern one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the legacy constructor example entirely from this section.

EXAMPLES.md Outdated
```kotlin
val netClient = DefaultClient.Builder()
.enableLogging(true)
.logLevel(HttpLoggingInterceptor.Level.HEADERS) // NONE, BASIC, HEADERS, or BODY (default)
Copy link
Contributor

@pmathew92 pmathew92 Feb 16, 2026

Choose a reason for hiding this comment

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

Log level support is not added. Only the custom logger is added
Remove log level from example

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed logLevel from the Kotlin example.

EXAMPLES.md Outdated
);
DefaultClient netClient = new DefaultClient.Builder()
.enableLogging(true)
.logLevel(HttpLoggingInterceptor.Level.HEADERS)
Copy link
Contributor

Choose a reason for hiding this comment

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

Log level support not added

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed logLevel from the Java example.

EXAMPLES.md Outdated

### Set additional headers for all requests
<details>
<summary>Legacy constructor (still supported)</summary>
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 legacy one from examples

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the entire legacy constructor

Details block from the "Set additional headers" section.

EXAMPLES.md Outdated
</details>

<details>
<summary>Legacy constructor (still supported)</summary>
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove legacy one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

EXAMPLES.md Outdated
```
</details>

### Custom interceptors
Copy link
Contributor

Choose a reason for hiding this comment

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

Custom interceptors are not supported. Remove this section

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the entire section.

.callTimeout(120)
.enableLogging(true)
.logLevel(HttpLoggingInterceptor.Level.HEADERS)
.addInterceptor(myCustomInterceptor)
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 addInterceptor from here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

.writeTimeout(30)
.callTimeout(120)
.enableLogging(true)
.logLevel(HttpLoggingInterceptor.Level.HEADERS)
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove logLevel from here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@utkrishtsahu utkrishtsahu merged commit 2264e8e into v4_development Feb 16, 2026
6 checks passed
@utkrishtsahu utkrishtsahu deleted the builder-pattern-default-client branch February 16, 2026 06:42
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

Comments