Skip to content

Conversation

@typotter
Copy link
Collaborator

@typotter typotter commented Jan 19, 2026

📚 Downstream SDK Extensibility Stacked Pull Requests 📚

👉 Extract DTO interfaces for downstream SDK extensibility (this PR)
🔲 Add HTTP ETag-based caching for configuration fetches (#202)
🔲 Extract IConfigurationSource interface for pluggable configuration loading (#203)
🔲 Make OkHttp a peer dependency for version flexibility (#204)

Motivation and Context

In order to support more flexible and custom configuration sources and parsing, we need to provide interfaces.

Currently, all DTOs are concrete classes in cloud.eppo.ufc.dto. The goal is to make it possible for downstream SDKs/Customers to:

  1. Manage network request pooling / networking package dependencies (ex: OKHttp)
  2. Provide platform-specific implementations (e.g., Kotlin data classes for Android)
  3. Use platform-specific serialization (e.g., Kotlinx.serialization instead of Jackson/Android builtins)

This PR extracts public interfaces for all DTOs

Description

Extract public interfaces for all 17 DTOs in the cloud.eppo.api package.

How has this been documented?

  • Comprehensive Javadoc on all 17 interfaces
  • Package location (cloud.eppo.api) clearly signals public API
  • Interface method contracts fully documented
  • No user-facing documentation needed (sdk-common-jdk is not directly consumed by end users)

How has this been tested?

Automated Testing

./gradlew compileJava  # Verify compilation
./gradlew test         # Run full test suite

Results:
✅ Compiles without errors
✅ All 249 tests passing
✅ No test modifications required (interfaces are transparent)

Verified Scenarios

  1. DTO→Interface casting: All DTOs can be safely cast to their interfaces
  2. Type-safe generics: Wildcard types (? extends IFlagConfig) work correctly
  3. Jackson deserialization: Still produces concrete classes as expected
  4. Method delegation: Interface calls delegate to concrete implementations
  5. Configuration storage: Generic type parameters work with interface types

Breaking Changes

  • Public API methods to use interfaces instead of concrete Classes

Create public interfaces (I* prefix) for all DTOs in cloud.eppo.api package:
- IFlagConfig, IFlagConfigResponse, IAllocation, ISplit, IShard, IShardRange
- ITargetingRule, ITargetingCondition, IVariation
- IBanditParameters, IBanditParametersResponse, IBanditReference
- IBanditModelData, IBanditCoefficients, IBanditFlagVariation
- IBanditAttributeCoefficients, IBanditNumericAttributeCoefficients, IBanditCategoricalAttributeCoefficients
- IEppoValue

Update DTOs to implement interfaces:
- All DTOs in cloud.eppo.ufc.dto now implement their corresponding interfaces
- EppoValue implements IEppoValue
- ShardRange implements IShardRange

Update consumers to use interface types:
- Configuration stores and returns interface types (Map<String, ? extends IFlagConfig>)
- FlagEvaluator, RuleEvaluator, BanditEvaluator use interface types
- BaseEppoClient uses IFlagConfig, IBanditParameters

This enables downstream SDKs (Android, KMP) to provide custom DTO implementations
while maintaining type safety and compatibility with the common SDK.
@typotter typotter changed the title Typo/dto interface extraction feat: extract DTO interfaces for downstream SDK extensibility Jan 20, 2026
@typotter typotter changed the title feat: extract DTO interfaces for downstream SDK extensibility Configuration Source Extraction part 1/4 Jan 20, 2026
@aarsilv aarsilv requested a review from Copilot January 20, 2026 18:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extracts public interfaces for all 17 DTOs in the cloud.eppo.api package to enable downstream SDK extensibility. The changes allow downstream SDKs and customers to provide custom implementations for configuration management, networking, and serialization while maintaining backward compatibility.

Changes:

  • Created 17 new interface definitions in cloud.eppo.api package
  • Updated all concrete DTO classes to implement their corresponding interfaces
  • Modified internal code to use interface types instead of concrete classes
  • Added backward compatibility methods where needed

Reviewed changes

Copilot reviewed 44 out of 44 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/main/java/cloud/eppo/api/I*.java (17 files) New interface definitions for all DTOs with comprehensive Javadoc
src/main/java/cloud/eppo/ufc/dto/*.java Updated concrete classes to implement new interfaces
src/main/java/cloud/eppo/api/Configuration.java Changed to use interface types for flags, bandits, and references
src/main/java/cloud/eppo/BaseEppoClient.java Updated to use IFlagConfig and IBanditParameters interfaces
src/main/java/cloud/eppo/FlagEvaluator.java Modified to work with interface types throughout evaluation logic
src/main/java/cloud/eppo/BanditEvaluator.java Updated to use IBanditModelData and related interfaces
src/main/java/cloud/eppo/RuleEvaluator.java Changed to use ITargetingRule and ITargetingCondition interfaces
src/test/java/cloud/eppo/BaseEppoClientTest.java Updated test to use IFlagConfig interface

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@typotter typotter changed the base branch from main to feature/v4 January 20, 2026 20:30
…ents

Remove EppoValue overload methods - use IEppoValue consistently.
Breaking change acceptable since targeting feature/v4.
…interface

Delete internal BanditAttributeCoefficients interface - use IBanditAttributeCoefficients everywhere.
Concrete classes now only implement the public interface.
Breaking change acceptable since targeting feature/v4.
- FlagEvaluationResult now uses IVariation throughout
- Remove concrete Variation from public API
- Remove wildcard imports of cloud.eppo.ufc.dto
- Only import specific types needed (VariationType enum)
- Breaking change: getVariation() returns IVariation instead of Variation
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