doc/cli-guideline: Apply suggestions from code review

Thanks Valentin!
This commit is contained in:
Robert Hensing 2023-02-27 16:21:40 +01:00 committed by Robert Hensing
parent f09ccd8ea9
commit 17f70b10bf

View File

@ -391,45 +391,39 @@ status section, but only print warnings and errors.
## Returning future proof JSON
The machine-readable JSON output should be extensible. This means that the
structure of the JSON should support the addition of extra information in many
places.
The schema of JSON output should allow for backwards compatible extension. This section explains how to achieve this.
Two definitions are helpful here, because while JSON only defines one "key-value"
object, we use it to cover two use cases:
object type, we use it to cover two use cases:
- **dictionary**: a map from names to things that all have the same type. In
- **dictionary**: a map from names to value that all have the same type. In
C++ this would be a `std::map` with string keys.
- **record**: a fixed set of attributes each with their own type. In C++, this
would be represented by a struct.
would be represented by a `struct`.
It is best not to mix these use cases, as that leads to incompatibilities and
other bugs. For example, adding a record field to a dictionary breaks consumers
that assume all JSON object fields to have the same meaning and type.
It is best not to mix these use cases, as that may lead to incompatibilities when the schema changes. For example, adding a record field to a dictionary breaks consumers that assume all JSON object fields to have the same meaning and type.
This leads to the following guidelines:
- **The top-level value** (or **root** of the returned data structure) **must be a record**.
Without this rule, it would be impossible to add per-invocation metadata in
a manner that doesn't break existing consumers.
- The top-level (root) value must be a record.
- **The value of a dictionary item must always be a record**. As an example,
suppose a command returns a dictionary where each key is the name of a store
type and each value is itself a dictionary representing settings.
Otherwise, one can not change the structure of a command's output.
- **List items should be records**. For example, a list of strings is not an
extensible type, as any additions will break code that expects a list of
strings.
If the list is unordered and it has a unique key that is a string, consider
a dictionary instead of a list. If the order of the items needs to be
preserved, return a list of records.
- The value of a dictionary item must be a record.
- **Streaming JSON should return records**. An example of a streaming JSON
format is "JSON lines", where multiple JSON values are streamed by putting
each on its own line in a text stream. These JSON values can be considered
top-level values or list items, and they must be records.
Otherwise, the item type can not be extended.
Examples:
- List items should be records.
Otherwise, one can not change the structure of the list items.
If the order of the items does not matter, and each item has a unique key that is a string, consider representing the list as a dictionary instead. If the order of the items needs to be preserved, return a list of records.
- Streaming JSON should return records.
An example of a streaming JSON format is [JSON lines](https://jsonlines.org/), where each line represents a JSON value. These JSON values can be considered top-level values or list items, and they must be records.
### Examples
```javascript
// bad: all keys must be assumed to be store implementations