Skip to content

feat: pass Dictionary to flag evaluation - #193

Merged
fabriziodemaria merged 21 commits into
mainfrom
eval-structs
Jun 27, 2025
Merged

feat: pass Dictionary to flag evaluation#193
fabriziodemaria merged 21 commits into
mainfrom
eval-structs

Conversation

@fabriziodemaria

@fabriziodemaria fabriziodemaria commented Apr 30, 2025

Copy link
Copy Markdown
Member

Behaviour

  • Only Dictionaries are allowed as default value when trying to evaluate a complex value
  • All the default value keys and their type must be found in the remote schema, otherwise it's a failed evaluation
    • The remote flag can have more keys than the default value Dictionary: those will be ignored and not part of the returned value (makes it safe to add fields to the flag definition later)
    • The opposite is not true: if the default value has a key that is not found in the remote flag, the entire evaluation fail
    • If any field from remote is null, whatever default value defined for that field is returned (regardless of its type ⚠️ )
  • On failed evaluations, always return whatever default value was passed in
  • If using OpenFeature, the custom OpenFeature.Value is required a default value.
    • The same semantics on keys/types mapping applies

Supported complex types

✅ defaultValue: ["size": 0] # Dictionary
❓ defaultValue: DefVal(size: 0) # struct (see wip. Could we expose this too, eventually?)
❌ defaultValue: ["size": ConfidenceValue.init(integer: 0)] # Dict with ConfidenceValue
❌ defaultValue: ConfidenceValue.init(structure: ["size": ConfidenceValue.init(integer: 0)]) # ConfidenceValue

Address #190

@fabriziodemaria
fabriziodemaria force-pushed the eval-structs branch 3 times, most recently from b250056 to 765d4de Compare June 9, 2025 12:28
@fabriziodemaria
fabriziodemaria force-pushed the eval-structs branch 3 times, most recently from 64d7580 to 4385b93 Compare June 17, 2025 14:41
@fabriziodemaria fabriziodemaria changed the title feat: Add support for Struct evaluations feat: pass Dictionary to flag evaluation Jun 17, 2025

@nicklasl nicklasl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

First off; great work taking this on and pushing through! And 👏 for writing such detailed tests, really helped me!

Secondly; I'm a bit mixed with all of this. It just becomes a bit less type safe than what I would like when you might get back a Dict<String, Any>. However; in those cases that was actually exactly what you passed in, so maybe it's fine?

I would have suggested we went straight to custom Struct support but we do need this to comply with OpenFeature though so 🤷.
Somewhere in my review I left a comment about the case when we have an additional key in the default value and that "breaks" the flag evaluation. If we could allow that, I'd be all good with this.

Comment thread Tests/ConfidenceProviderTests/ConfidenceProviderTest.swift
Comment on lines +512 to +516
// New behavior: should fail because the "error" key is missing from the flag structure
XCTAssertEqual(evaluation.value as? [String: AnyHashable], ["width": 100, "color": "black", "error": "Unknown"])
XCTAssertEqual(evaluation.errorCode, .typeMismatch(
message: "Default value key \'error\' not found in flag"))
XCTAssertEqual(evaluation.errorMessage, "Default value key \'error\' not found in flag")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am not sure about this behaviour TBH.
Why am I as a user of the SDK not allowed to have other dict keys in the default values compared to what Confidence assigns?
As a developer, this would prevent me from evolving my feature (or how I am using the feature flag) before implementing the new schema in Confidence.

@fabriziodemaria fabriziodemaria Jun 24, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Here is a potential pitfall with the mixed approach: if we have a remote variant { "size": 3 } and a default value { "sze": 10 } (with a typo), there would be no evaluation errors and possibly the devs will keep using size 10 around their codebase even if the exposure is for size 3. Not sure how much we should care about this, but it's definitely something more bug prone than failing with: "sze" not found in the remote flag.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Another potential pitfall of having certain fields only in the default value is that if we later add the corresponding fields in the remote schema but with a different type we will break existing evaluations. Adding properties to a flag in the UI should always be a "safe operation".

As a developer, this would prevent me from evolving my feature (or how I am using the feature flag) before implementing the new schema in Confidence.

I am thinking devs can still try out the flag locally using the default value. But in order to resolve remote correctly, all the default keys must match the flag's remote schema: perhaps this is a reasonable ask

Comment thread Tests/ConfidenceProviderTests/ConfidenceProviderTest.swift
Comment thread Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift Outdated
Comment thread Sources/Confidence/FlagEvaluation.swift Outdated
Comment thread Sources/Confidence/FlagEvaluation.swift
@fabriziodemaria
fabriziodemaria marked this pull request as ready for review June 26, 2025 09:58
@fabriziodemaria
fabriziodemaria force-pushed the eval-structs branch 4 times, most recently from a1e5a01 to adee881 Compare June 26, 2025 11:34
vahidlazio
vahidlazio previously approved these changes Jun 27, 2025
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.

3 participants