Home Explore Blog Models CI



nix

1st chunk of `doc/manual/source/development/json-guideline.md`
6767e47e35506af2bf0938a95e807dcbfb6bbd60835a5ec300000001000008cc
# JSON guideline

Nix consumes and produces JSON in a variety of contexts.
These guidelines ensure consistent practices for all our JSON interfaces, for ease of use, and so that experience in one part carries over to another.

## Extensibility

The schema of JSON input and 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 type, we use it to cover two use cases:

 - **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`.

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, and dictionary items with a colliding name can not be represented anymore.

This leads to the following guidelines:

 - The top-level (root) value must be a record.

   Otherwise, one can not change the structure of a command's output.

 - The value of a dictionary item must be a record.

   Otherwise, the item type can not be extended.

 - 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

This is bad, because all keys must be assumed to be store types:

```json
{
  "local": { ... },
  "remote": { ... },
  "http": { ... }
}
```

This is good, because the it is extensible at the root, and is somewhat self-documenting:

```json
{
  "storeTypes": { "local": { ... }, ... },
  "pluginSupport": true

Title: Nix JSON Guidelines: Extensibility
Summary
This document provides guidelines for creating extensible JSON schemas within Nix, aiming for consistency and ease of use across its JSON interfaces. It differentiates between 'dictionary' (map of same-type values) and 'record' (fixed set of typed attributes) objects, advising against mixing them to prevent schema incompatibilities. Key guidelines include ensuring that the top-level (root) value, dictionary item values, list items, and streaming JSON values are all records, which allows for backward-compatible extensions and future modifications to the data structure. Examples are provided to illustrate these principles.