asyncapi / asyncapi/spec

Handling `null` values in the trait merge mechanism

Open
#1,178 2 comments 0 reactions 0 assignees View on GitHub
❔ Question
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.