|
| 1 | +# 6. Optional value field for code default deferral |
| 2 | + |
| 3 | +Date: 2025-07-29 |
| 4 | + |
| 5 | +## Status |
| 6 | + |
| 7 | +Proposed |
| 8 | + |
| 9 | +## Context |
| 10 | + |
| 11 | +Feature flag management systems often follow a standard release lifecycle where flags transition through different states. During early stages of a feature rollout, it's common practice to defer to the default value defined in the application code rather than returning an explicit value from the flag management system. |
| 12 | + |
| 13 | +This pattern provides several benefits: |
| 14 | +- Developers define default values once in code, avoiding duplication in the flag management system |
| 15 | +- Flag management systems can gradually roll out features without needing to know the code default value |
| 16 | +- The transition from code defaults to managed values becomes part of the standard feature flag lifecycle |
| 17 | + |
| 18 | +Currently, OFREP requires the `value` field to be present in all successful evaluation responses. This forces flag management systems to either: |
| 19 | +1. Duplicate the default value from code into their system |
| 20 | +2. Return an error response when they want to defer to code defaults (misleading telemetry and error handling) |
| 21 | + |
| 22 | +Neither approach is ideal. Returning errors for what is actually a successful evaluation leads to incorrect metrics and may trigger error handling logic in applications. |
| 23 | + |
| 24 | +## Decision |
| 25 | + |
| 26 | +Introduce a new flag type schema `codeDefaultFlag` that explicitly indicates the provider should use the default value defined in the application code. This new type would be used alongside existing flag types (booleanFlag, stringFlag, etc.) in evaluation responses. |
| 27 | + |
| 28 | +Key implementation details: |
| 29 | +- Add a new `codeDefaultFlag` schema type with no `value` field |
| 30 | +- Existing flag type schemas remain unchanged (backward compatible) |
| 31 | +- When a response uses `codeDefaultFlag` type, providers MUST use the code default value |
| 32 | +- All other fields in the evaluation response (key, reason, variant, metadata) remain unchanged |
| 33 | +- This behavior applies to both single flag evaluations and bulk evaluations |
| 34 | +- The `oneOf` discriminator in evaluation responses would include this new type |
| 35 | + |
| 36 | +Example OpenAPI schema addition: |
| 37 | +```yaml |
| 38 | +codeDefaultFlag: |
| 39 | + description: A flag evaluation that defers to the code default value |
| 40 | + type: object |
| 41 | + # Note: No value property - provider must use code default |
| 42 | +``` |
| 43 | + |
| 44 | +The evaluation success response would be updated to include this type: |
| 45 | +```yaml |
| 46 | +- oneOf: |
| 47 | + - $ref: "#/components/schemas/booleanFlag" |
| 48 | + - $ref: "#/components/schemas/stringFlag" |
| 49 | + - $ref: "#/components/schemas/integerFlag" |
| 50 | + - $ref: "#/components/schemas/floatFlag" |
| 51 | + - $ref: "#/components/schemas/objectFlag" |
| 52 | + - $ref: "#/components/schemas/codeDefaultFlag" # New type |
| 53 | +``` |
| 54 | +
|
| 55 | +Example response deferring to code default: |
| 56 | +```json |
| 57 | +{ |
| 58 | + "key": "new-feature", |
| 59 | + "reason": "DEFAULT", |
| 60 | + "variant": "control" |
| 61 | + // No value field - indicates codeDefaultFlag type |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +Example response with explicit value (existing behavior): |
| 66 | +```json |
| 67 | +{ |
| 68 | + "key": "new-feature", |
| 69 | + "value": true, |
| 70 | + "reason": "TARGETING_MATCH", |
| 71 | + "variant": "treatment" |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +## Consequences |
| 76 | + |
| 77 | +### Positive |
| 78 | + |
| 79 | +- **Eliminates default value duplication**: Developers maintain default values in one place (code) rather than synchronizing between code and flag management system |
| 80 | +- **Supports standard feature flag lifecycle**: Natural progression from code defaults to managed values |
| 81 | +- **Accurate telemetry**: Deferred evaluations are correctly recorded as successful rather than errors |
| 82 | +- **Flexibility for flag management systems**: Systems can choose when to provide explicit values vs. deferring to code |
| 83 | +- **Backward compatible**: Existing implementations continue to work without modification |
| 84 | + |
| 85 | +### Negative |
| 86 | + |
| 87 | +- **Breaking change for providers**: While the API remains backward compatible, all provider implementations must be updated to handle the new `codeDefaultFlag` type. This change should be implemented before the 1.0 release. |
| 88 | +- **Delayed type mismatch detection**: When deferring to code defaults, type mismatches between the flag configuration and code won't be detected until the flag management system returns an explicit value. This could lead to runtime errors that would have been caught earlier with mandatory values. |
| 89 | +- **Provider complexity**: Providers must carefully handle the new flag type case and ensure code defaults are always available when needed. |
| 90 | + |
| 91 | +### Implementation Requirements |
| 92 | + |
| 93 | +1. **Provider updates**: All OFREP providers must be updated to: |
| 94 | + - Recognize the `codeDefaultFlag` type in responses |
| 95 | + - Use code default values when this type is received |
| 96 | + - Maintain existing behavior for other flag types |
| 97 | + |
| 98 | +2. **Type validation**: Providers should validate that code default types match expected flag types when possible, though this validation may be limited when values are omitted. |
| 99 | + |
| 100 | +3. **Error handling**: Providers must ensure that appropriate errors are returned if a code default is not available when the `codeDefaultFlag` type is used. |
| 101 | + |
| 102 | +4. **Bulk evaluations**: The same logic applies - individual flags within a bulk response may use the `codeDefaultFlag` type independently. |
0 commit comments