Handling `null` values in the trait merge mechanism
- Dominant language
- JavaScript
- Stars
- 5.3k
- Forks
- 382
- Avg merge
- 7m
- Merged PRs (30d)
- 4
Description
The specification does not explicitly define how `null` values in traits or target objects should be interpreted.
While it references the JSON Merge Patch algorithm (which assigns special meaning to `null` values in merge patches), it also states that "a property on a trait MUST NOT override the same property on the target object." This creates ambiguity regarding how to reconcile the special meaning of `null` values in a patch with this overriding restriction.
I have tested several examples and examined the output from the `@asyncapi/parser`. The results differ depending on whether it is a top-level property (directly under the Operation/Operation Trait Object) or a nested property (e.g., within a binding under the Operation/Operation Trait Object), which is confusing.
Could you please clarify how `null` values should be interpreted in the trait merge mechanism—and whether they should be interpreted at all?
```javascript
// operations.myOperation['x-test'] === null
// operations.myOperation.bindings.kafka['x-test'] === null
const spec = {
asyncapi: '3.0.0',
info: {
title: 'Object null properties, no traits merge',
version: '1.0',
},
channels: {
myChannel: {}
},
operations: {
myOperation: {
action: 'send',
channel: {
$ref: '#/channels/myChannel'
},
'x-test': null,
bindings: {
kafka: {
'x-test': null
}
}
}
}
}
```
```javascript
// operations.myOperation['x-test'] === null
// operations.myOperation.bindings.kafka['x-test'] === undefined
const spec = {
asyncapi: '3.0.0',
info: {
title: 'Object null properties, trigger traits merge',
version: '1.0',
},
channels: {
myChannel: {}
},
operations: {
myOperation: {
action: 'send',
channel: {
$ref: '#/channels/myChannel'
},
'x-test': null,
bindings: {
kafka: {
'x-test': null
}
},
traits: [
{}
]
}
}
}
```
```javascript
// operations.myOperation['x-test'] === null
// operations.myOperation.bindings.kafka['x-test'] === undefined
const spec = {
asyncapi: '3.0.0',
info: {
title: 'Trait null properties',
version: '1.0',
},
channels: {
myChannel: {}
},
operations: {
myOperation: {
action: 'send',
channel: {
$ref: '#/channels/myChannel'
},
traits: [
{
'x-test': null,
bindings: {
kafka: {
'x-test': null
}
},
}
]
}
}
}
```
Contributor guide
Research direction
Read the JSON Merge Patch reference and the trait merge wording, then reproduce the three examples with @asyncapi/parser. Compare how null behaves in top-level and nested properties. Done means the specification explicitly defines whether null is interpreted and gives consistent behavior for both locations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- backend-api-design, documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100