Skip to content

Redesign StreamClient factory with StreamSocketConfig and StreamComponentProvider#54

Open
aleksandar-apostolov wants to merge 5 commits intodevelopfrom
feat/client-config
Open

Redesign StreamClient factory with StreamSocketConfig and StreamComponentProvider#54
aleksandar-apostolov wants to merge 5 commits intodevelopfrom
feat/client-config

Conversation

@aleksandar-apostolov
Copy link
Copy Markdown
Collaborator

@aleksandar-apostolov aleksandar-apostolov commented Apr 9, 2026

Goal

Redesign the StreamClient factory API so that product SDKs (Feeds, Video, Chat) can configure their client with a clear, self-documenting signature — no hidden config bags, no ambiguous defaults.

Implementation

Before: Single factory with 15+ params, StreamClientConfig wrapper hiding tunables, hardcoded chat WS URL default, retryProcessor param that wasn't used.

After: Flat factory with clear separation:

StreamClient(
    // Identity — what you are
    scope, context, user, tokenProvider, products,
    // Connection — how you connect
    socketConfig = StreamSocketConfig.jwt(url, apiKey, clientInfo, ...),
    // Serialization — how you parse events
    serializationConfig = StreamClientSerializationConfig.default(mySerializer),
    // HTTP — optional REST config
    httpConfig = StreamHttpConfig(...),
    // DI — optional component overrides
    components = StreamComponentProvider(logProvider = ..., singleFlight = ...),
)

Key changes:

  • StreamSocketConfig — required, holds URL (StreamWsUrl, type-safe), auth type (jwt/anonymous/custom), API key, client info header, plus operational tunables (health timing, batch params, connection timeout). Factory methods: .jwt(), .anonymous(), .custom()
  • StreamComponentProvider — optional DI overrides for internal components. Now also holds logProvider (with sensible default)
  • StreamClientConfig deletedserializationConfig and httpConfig promoted to top-level factory params
  • No hardcoded defaults — products must specify their WS URL (no chat-specific fallback in core)
  • retryProcessor removed — building block, not a client concern
  • connectionTimeoutMs added — configurable per socket (default 10s)
  • authType exposed — anonymous connections now possible (Chat needs this)

Files changed:

File Change
StreamClient.kt New public + internal factory signatures
StreamSocketConfig.kt StreamWsUrl + operational tunables + 3 factory methods
StreamClientConfig.kt Deleted
StreamComponentProvider.kt Added logProvider
StreamWebSocketFactoryImpl.kt Uses config.url.rawValue
SampleApp.kt Migrated to new API
StreamClientConfigFactoryTest.kt 14 tests for public factory
StreamClientFactoryTest.kt Updated for new internal factory
StreamSocketConfigTest.kt Tests for defaults + custom operational params
StreamWebSocketFactoryImplTest.kt Updated for StreamWsUrl
StreamSocketSessionTest.kt Updated for StreamWsUrl

Testing

  • 618 unit tests pass (1 pre-existing failure in StreamCompositeEventSerializationImplTest — unrelated)
  • New tests cover: socket config wiring, health timing, batch params, component injection, combined config + components
  • Spotless + detekt clean

pr: breaking-change

Split StreamClient construction into three clear concerns:
- Function params: mandatory identity (apiKey, user, tokenProvider, etc.)
- StreamClientConfig: optional tunables (wsUrl, health check timing,
  batch sizes, logging) with sensible defaults
- StreamComponentProvider: optional DI overrides for replacing internal
  components (singleFlight, tokenManager, etc.)

The simplified StreamClient() factory becomes the public API. The
original 25-param factory is now internal (createStreamClientInternal)
for test use.

Removes retryProcessor from factory params as StreamClientImpl never
consumed it — products create their own instances directly.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled.

🎉 Great job! This PR is ready for review.

@aleksandar-apostolov aleksandar-apostolov added the pr:breaking-change Breaking change label Apr 9, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Walkthrough

StreamClient's public factory API is refactored with a simplified required-parameter signature and two new configuration data classes—StreamClientConfig and StreamComponentProvider—enabling optional behavior tuning and component injection. The retryProcessor parameter is removed, and monitoring parameters become nullable with default instantiation in the internal factory.

Changes

Cohort / File(s) Summary
StreamClient Factory Refactoring
stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt
Public factory signature simplified to require scope, context, apiKey, user, tokenProvider, products, clientInfoHeader, and productEventSerializer, with optional config and components parameters. Internal createStreamClientInternal removes retryProcessor; networkMonitor, lifecycleMonitor, and connectionRecoveryEvaluator are now nullable with defaults created if omitted.
Configuration & Component Data Classes
stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamClientConfig.kt, stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamComponentProvider.kt
Introduces two new data classes: StreamClientConfig holds tuning parameters (wsUrl, logProvider, health/batch timing, serialization config), and StreamComponentProvider provides nullable overrides for internal components (singleFlight, serialQueue, tokenManager, batcher, monitors, etc.).
Test Updates
stream-android-core/src/test/java/io/getstream/android/core/api/StreamClientFactoryTest.kt
Removes StreamRetryProcessor from test dependencies and imports; updates client creation helpers to call createStreamClientInternal instead of public StreamClient constructor.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A rabbit hops through simpler paths,
With configs clean and components fit,
No retry ghosts to haunt the way,
Just optional overrides, hooray!
The factory dances, light and fleet!

🚥 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
Title check ✅ Passed The title clearly summarizes the main change: introducing StreamSocketConfig and StreamComponentProvider as part of a redesign of the StreamClient factory API.
Description check ✅ Passed The description is comprehensive and well-structured, covering Goal, Implementation with detailed explanations and code examples, Testing, and a Checklist section matching the template.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/client-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

🧹 Nitpick comments (1)
stream-android-core/src/test/java/io/getstream/android/core/api/StreamClientFactoryTest.kt (1)

336-358: Consider adding test coverage for the new public StreamClient() factory.

The tests now use createStreamClientInternal() directly, which is appropriate for detailed wiring verification. However, there's no test exercising the new public StreamClient(config, components) signature to verify that StreamClientConfig and StreamComponentProvider are correctly resolved and delegated.

Would you like me to generate a test case that verifies the public factory correctly wires StreamClientConfig tunables and StreamComponentProvider overrides?

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

In
`@stream-android-core/src/test/java/io/getstream/android/core/api/StreamClientFactoryTest.kt`
around lines 336 - 358, Tests call createStreamClientInternal(...) but do not
exercise the new public StreamClient(config, components) factory; add a unit
test that constructs a StreamClient using the public
StreamClient(StreamClientConfig, StreamComponentProvider) API and asserts it
delegates to the same wiring as createStreamClientInternal — e.g., build a
StreamClientConfig with the same tunables (apiKey, user, wsUrl, products,
clientInfoHeader, tokenProvider, serializationConfig) and a fake
StreamComponentProvider (similar to fakeAndroidComponents/logProvider), call
StreamClient(config, components), then verify resulting client's behavior or
internals match what createStreamClientInternal produces (or spy/mock the
underlying components to assert they were used). Ensure the test lives alongside
StreamClientFactoryTest and references StreamClient, StreamClientConfig,
StreamComponentProvider, and createStreamClientInternal to validate delegation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt`:
- Around line 207-280: The SampleApp.kt call to the StreamClient factory must be
updated because the public StreamClient(...) signature changed:
productEventSerializer is now a required parameter and wsUrl/serializationConfig
were moved into StreamClientConfig; update the StreamClient invocation in
SampleApp.kt to pass a productEventSerializer implementation as the 8th argument
and set wsUrl and serializationConfig inside the config =
StreamClientConfig(...) parameter (instead of passing wsUrl/serializationConfig
directly), keeping other arguments (scope, context, apiKey, user, tokenProvider,
products, clientInfoHeader) unchanged so the call matches the new
StreamClient(...) factory.

---

Nitpick comments:
In
`@stream-android-core/src/test/java/io/getstream/android/core/api/StreamClientFactoryTest.kt`:
- Around line 336-358: Tests call createStreamClientInternal(...) but do not
exercise the new public StreamClient(config, components) factory; add a unit
test that constructs a StreamClient using the public
StreamClient(StreamClientConfig, StreamComponentProvider) API and asserts it
delegates to the same wiring as createStreamClientInternal — e.g., build a
StreamClientConfig with the same tunables (apiKey, user, wsUrl, products,
clientInfoHeader, tokenProvider, serializationConfig) and a fake
StreamComponentProvider (similar to fakeAndroidComponents/logProvider), call
StreamClient(config, components), then verify resulting client's behavior or
internals match what createStreamClientInternal produces (or spy/mock the
underlying components to assert they were used). Ensure the test lives alongside
StreamClientFactoryTest and references StreamClient, StreamClientConfig,
StreamComponentProvider, and createStreamClientInternal to validate delegation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8c81a6e9-ff46-4e43-a1b5-b49a196c325e

📥 Commits

Reviewing files that changed from the base of the PR and between fe08323 and 8d4f70c.

📒 Files selected for processing (4)
  • stream-android-core/src/main/java/io/getstream/android/core/api/StreamClient.kt
  • stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamClientConfig.kt
  • stream-android-core/src/main/java/io/getstream/android/core/api/model/config/StreamComponentProvider.kt
  • stream-android-core/src/test/java/io/getstream/android/core/api/StreamClientFactoryTest.kt

Update SampleApp to use the simplified StreamClient factory with
StreamClientConfig for tunables and productEventSerializer as a
direct parameter.
@aleksandar-apostolov aleksandar-apostolov changed the title feat(config): introduce StreamClientConfig and StreamComponentProvider Introduce StreamClientConfig and StreamComponentProvider Apr 9, 2026
@aleksandar-apostolov aleksandar-apostolov changed the title Introduce StreamClientConfig and StreamComponentProvider Introduce StreamClientConfig and StreamComponentProvider for easier configuration in the products Apr 9, 2026
…Provider factory

Verify that the public StreamClient(config, components) factory correctly
wires all StreamClientConfig tunables (wsUrl, health timing, batch params,
serialization) and StreamComponentProvider overrides (singleFlight,
serialQueue, tokenManager, connectionIdHolder, socketFactory, healthMonitor,
batcher, subscriptionManager) through to internal components.
… required

- StreamSocketConfig now holds URL (as StreamWsUrl), auth, health timing,
  batch params, and connection timeout — products describe their socket
- StreamClientConfig slimmed to logProvider, httpConfig, serializationConfig
- StreamClient factory takes socketConfig as required param; apiKey and
  clientInfoHeader removed from top-level (live in socketConfig)
- No more hardcoded chat wsUrl default — products must specify their endpoint
- HTTP interceptors read apiKey/authType/clientInfo from socketConfig
- Added connectionTimeoutMs to StreamSocketConfig (default 10s)
- Updated sample app, all factory tests, socket config tests
- Remove StreamClientConfig — serializationConfig and httpConfig are now
  top-level params on StreamClient factory, logProvider moves to
  StreamComponentProvider
- StreamClient factory signature: scope, context, user, tokenProvider,
  products, socketConfig, serializationConfig, httpConfig?, components?
- Products pass StreamClientSerializationConfig.default(serializer) directly
- No hidden config bags — everything visible at the call site
@aleksandar-apostolov aleksandar-apostolov changed the title Introduce StreamClientConfig and StreamComponentProvider for easier configuration in the products Redesign StreamClient factory with StreamSocketConfig and StreamComponentProvider Apr 14, 2026
@sonarqubecloud
Copy link
Copy Markdown

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

Labels

pr:breaking-change Breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant