-
Notifications
You must be signed in to change notification settings - Fork 88
chore(ADR): Proposal to add flag type #1746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
andreyturkov
wants to merge
15
commits into
open-feature:main
Choose a base branch
from
andreyturkov:proposal/flag-type
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
e08b2a0
proposal: added draft propsal to add new flag-type field.
andreyturkov 1226202
proposal: text refinement and clean up
andreyturkov f1b01ef
chore: flag-type proposal updates
andreyturkov 8f4e080
chore: flag-type proposal updates
andreyturkov b8cfc68
chore: updated flag type ADR according to the remarks from PR
andreyturkov 6ef6fce
chore: updated flag type ADR according to the remarks from PR
andreyturkov 4a5081c
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov 06657c4
Merge branch 'open-feature:main' into proposal/flag-type
andreyturkov 02131d1
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov 639519a
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov fdd6b67
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov c132a88
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov effe9c7
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov a0157ca
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov 144378e
Signed-off-by: Andrey Turkov <andreyturkov@google.com>
andreyturkov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
--- | ||
status: proposed | ||
author: @andreyturkov | ||
created: 2025-08-14 | ||
updated: 2025-08-14 | ||
--- | ||
|
||
# Extending Flag Definition with a Type Property | ||
|
||
|
||
## Background | ||
|
||
Currently, `flagd` has inconsistent behavior in type validation between its `Resolve<T>` and `ResolveAll` API methods. The `Resolve<T>` method validates the evaluated flag variant against the type `T` requested by the client, while `ResolveAll` validates it against the type of the `defaultVariant` specified in the flag's definition. This discrepancy can lead to situations where a flag evaluation succeeds with one method but fails with the other, depending on the evaluation context and the variant returned. This inconsistent behavior is further detailed in bug report #1481. | ||
|
||
The root cause of this issue is the absence of a dedicated, authoritative type definition for the flag itself. Instead, the type is inferred from the `defaultVariant` or API itself (`T` from `Resolve<T>`) , which is not always a reliable source of truth for all possible variants. This can lead to unexpected errors and make it difficult for developers to debug their feature flags. | ||
|
||
|
||
## Requirements | ||
|
||
* The new `type` field in the flag definition must be optional to ensure backward compatibility. | ||
andreyturkov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
* If the `type` field is present, `flagd` must validate that all variants of the flag conform to this type during initialization. | ||
andreyturkov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
* Type mismatches found during initialization must be reported as errors. | ||
* The `Resolve<T>` and `ResolveAll` methods must use the `type` field for validation when it is available. | ||
* The implementation must be consistent with the OpenFeature specification and the flag manifest schema. | ||
andreyturkov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
## Considered Options | ||
|
||
* **Consistent `defaultVariant` Validation:** Align the behavior of `Resolve<T>` with `ResolveAll` by making `Resolve<T>` validate the evaluated variant against the type of the `defaultVariant`. | ||
* **API Extension with Explicit Flag Type:** Introduce an optional `type` property to the flag definition to serve as the authoritative source for type validation. | ||
|
||
|
||
## Proposal | ||
|
||
This proposal is to extend the flag definition with an optional `type` property. This approach is chosen over simply aligning the `Resolve<T>` and `ResolveAll` validation because it addresses the root cause of the type inconsistency and provides a more robust, long-term solution. | ||
|
||
By introducing an explicit `type` field, it establishes a single source of truth for the flag's type, independent of its variants. This allows for early and consistent type validation during flag definition parsing, preventing type-related errors at runtime. | ||
|
||
The new `type` field will be optional to maintain backward compatibility with existing flag configurations. If the field is omitted, `flagd` will treat the flag as having `object`, and no type validation will be performed against the `defaultVariant`. When the `type` field is present, `flagd` will enforce that all variants of the flag conform to the specified type. | ||
|
||
This change will make the behavior of `flagd` more predictable and reliable. | ||
|
||
|
||
### API changes | ||
|
||
The `flagd` flag definition will be updated to include an optional `type` property. This property will be a string enum with the following possible values: `"boolean"`, `"string"`, `"number"`, and `"object"`. | ||
andreyturkov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
|
||
#### JSON Schema | ||
|
||
The following changes will be made to the `schemas/json/flags.json` file: | ||
|
||
1. A new `type` property will be added to the `flag` definition: | ||
|
||
```json | ||
"flag": { | ||
"type": "object", | ||
"properties": { | ||
"type": { | ||
andreyturkov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
"title": "Flag Type", | ||
"description": "The type of the flag. If specified, all variants must conform to this type.", | ||
"type": "string", | ||
"enum": [ | ||
"boolean", | ||
"string", | ||
"number", | ||
"object" | ||
] | ||
}, | ||
"state": { | ||
... | ||
}, | ||
... | ||
} | ||
} | ||
``` | ||
|
||
2. The `booleanFlag`, `stringFlag`, `numberFlag`, and `objectFlag` definitions will be updated to enforce the `type` property: | ||
|
||
```json | ||
"booleanFlag": { | ||
"allOf": [ | ||
{ | ||
"$ref": "#/definitions/flag" | ||
}, | ||
{ | ||
"$ref": "#/definitions/booleanVariants" | ||
}, | ||
{ | ||
"properties": { | ||
"type": { | ||
"const": "boolean" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Similar changes will be made to `stringFlag`, `numberFlag`, and `objectFlag` to enforce their respective types. | ||
|
||
### Consequences | ||
|
||
#### The good | ||
* It improves the reliability and predictability of flag evaluations. | ||
* It allows for early error detection of type mismatches. | ||
* It improves the developer experience by making the API more explicit. | ||
|
||
#### The bad | ||
* It adds a new field to the flag definition, which developers need to be aware of. | ||
* It requires updating all `flagd` SDKs to support the new field. | ||
* It requires updating flag manifest schema | ||
andreyturkov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
andreyturkov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
### Timeline | ||
|
||
* **Phase 1: Core Implementation** | ||
* Update the `flagd` core to support the new `type` field. | ||
* Implement the type validation logic. | ||
* Update the JSON schema. | ||
andreyturkov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* Add unit and integration tests. | ||
* **Phase 2: SDK Updates** | ||
* Update all `flagd` SDKs to support the new `type` field. | ||
* Update flag manifest | ||
* **Phase 3: Documentation** | ||
* Update the `flagd` documentation to reflect the changes. | ||
|
||
|
||
|
||
## More Information | ||
|
||
* **Bug Report:** [https://github.com/open-feature/flagd/issues/1481](https://github.com/open-feature/flagd/issues/1481) | ||
* **Flag schema** [https://flagd.dev/schema/v0/flags.json](https://flagd.dev/schema/v0/flags.json) | ||
* **Flag Manifest Schema:** [https://raw.githubusercontent.com/open-feature/cli/refs/heads/main/schema/v0/flag-manifest.json](https://raw.githubusercontent.com/open-feature/cli/refs/heads/main/schema/v0/flag-manifest.json) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.