Files
lightning/doc/guides/Contribute to Core Lightning/coding-style-guidelines/writing-json-schemas.md
Adi Shankara e83782f5de doc: Add guides and GitHub workflow for doc sync
This PR:
- adds all the guides (in markdown format) that is published at https://docs.corelightning.org/docs
- adds a github workflow to sync any future changes made to files inside the guides folder
- does not include API reference (json-rpc commands). Those will be handled in a separate PR since they're used as manpages and will require a different github workflow

Note that the guides do not exactly map to their related files in doc/, since we reorganized the overall documentation structure on readme for better readability and developer experience. For example, doc/FUZZING.md and doc/HACKING.md#Testing are merged into testing.md in the new docs. As on the creation date of this PR, content from each of the legacy documents has been synced with the new docs. Until this PR gets merged, I will continue to push any updates made to the legacy documents into the new docs.

If this looks reasonable, I will add a separate PR to clean up the legacy documents from doc/ (or mark them deprecated) to avoid redundant upkeep and maintenance.

Changelog-None
2023-06-06 12:40:19 +09:30

3.5 KiB

title, slug, hidden, createdAt, updatedAt
title slug hidden createdAt updatedAt
Writing JSON Schemas writing-json-schemas false 2023-01-25T05:46:43.718Z 2023-01-30T15:36:28.523Z

A JSON Schema is a JSON file which defines what a structure should look like; in our case we use it in our testsuite to check that they match command responses, and also use it to generate our documentation.

Yes, schemas are horrible to write, but they're damn useful. We can only use a subset of the full JSON Schema Specification, but if you find that limiting it's probably a sign that you should simplify your JSON output.

Updating a Schema

If you add a field, you should add it to the schema, and you must add "added": "VERSION" (where VERSION is the next release version!).

Similarly, if you deprecate a field, add "deprecated": "VERSION" (where VERSION is the next release version). They will be removed two versions later.

How to Write a Schema

Name the schema doc/schemas/command.schema.json: the testsuite should pick it up and check all invocations of that command against it.

I recommend copying an existing one to start.

You will need to put the magic lines in the manual page so make doc-all will fill it in for you:

[comment]: # (GENERATE-FROM-SCHEMA-START)
[comment]: # (GENERATE-FROM-SCHEMA-END)

If something goes wrong, try tools/fromscheme.py doc/schemas/command.schema.json to see how far it got before it died.

You should always use "additionalProperties": false, otherwise your schema might not be covering everything. Deprecated fields simply have "deprecated": true in their properties, so they are allowed by omitted from the documentation.

You should always list all fields which are always present in "required".

We extend the basic types; see fixtures.py.

In addition, before committing a new schema or a new version of it, make sure that it is well formatted. If you don't want do it by hand, use make fmt-schema that uses jq under the hood.

Using Conditional Fields

Sometimes one field is only sometimes present; if you can, you should make the schema know when it should (and should not!) be there.

There are two kinds of conditional fields expressable: fields which are only present if another field is present, or fields only present if another field has certain values.

To add conditional fields:

  1. Do not mention them in the main "properties" section.
  2. Set "additionalProperties": true for the main "properties" section.
  3. Add an "allOf": [ array at the same height as "properties"'. Inside this place one if/then for each conditional field.
  4. If a field simply requires another field to be present, use the pattern "required": [ "field" ] inside the "if".
  5. If a field requires another field value, use the pattern
    "properties": { "field": { "enum": [ "val1", "val2" ] } } inside the "if".
  6. Inside the "then", use "additionalProperties": false and place empty {} for all the other possible properties.
  7. If you haven't covered all the possibilties with if statements, add an else with "additionalProperties": false which simply mentions every allowable property. This ensures that the fields can only be present when conditions are met.

JSON Drinking Game!

  1. Sip whenever you have an additional comma at the end of a sequence.
  2. Sip whenever you omit a comma in a sequence because you cut & paste.
  3. Skull whenever you wish JSON had comments.