Skip to content

Commit a9f49b5

Browse files
committed
doc: document how to try to write JSON schemas.
Signed-off-by: Rusty Russell <[email protected]>
1 parent fe161ff commit a9f49b5

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

Diff for: doc/STYLE.md

+6
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ All `warning` fields should have unique names which start with
194194
`warning_`, the value of which should be an explanation. This allows
195195
for programs to deal with them sanely, and also perform translations.
196196

197+
### Documenting JSON APIs
198+
199+
We use JSON schemas to validate that JSON-RPC returns are in the
200+
correct form, and also to generate documentation. See
201+
[doc/schemas/WRITING_SCHEMAS.md](WRITING_SCHEMAS.md).
202+
197203
## Changing JSON APIs
198204

199205
All JSON API changes need a Changelog line (see below).

Diff for: doc/schemas/WRITING_SCHEMAS.md

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Writing JSON Schemas
2+
3+
A JSON Schema is a JSON file which defines what a structure should
4+
look like; in our case we use it in our testsuite to check that they
5+
match command responses, and also use it to generate our
6+
documentation.
7+
8+
Yes, schemas are horrible to write, but they're damn useful. We can
9+
only use a subset of the full [https://json-schema.org/](JSON Schema
10+
Specification), but if you find that limiting it's probably a sign
11+
that you should simplify your JSON output.
12+
13+
## How to Write a Schema
14+
15+
Name the schema doc/schemas/`command`.schema.json: the testsuite should
16+
pick it up and check all invocations of that command against it.
17+
18+
I recommend copying an existing one to start.
19+
20+
You will need to put the magic lines in the manual page so `make doc-all`
21+
will fill it in for you:
22+
23+
```
24+
[comment]: # (GENERATE-FROM-SCHEMA-START)
25+
[comment]: # (GENERATE-FROM-SCHEMA-END)
26+
```
27+
28+
If something goes wrong, try tools/fromscheme.py
29+
doc/schemas/`command`.schema.json to see how far it got before it died.
30+
31+
You should always use `"additionalProperties": false`, otherwise
32+
your schema might not be covering everything. Deprecated fields
33+
simply have `"deprecated": true` in their properties, so they
34+
are allowed by omitted from the documentation.
35+
36+
You should always list all fields which are *always* present in
37+
`"required"`.
38+
39+
We extend the basic types; see
40+
[contrib/pyln-testing/pyln/testing/fixtures.py](fixtures.py).
41+
42+
43+
### Using Conditional Fields
44+
45+
Sometimes one field is only sometimes present; if you can, you should make
46+
the schema know when it should (and should not!) be there.
47+
48+
There are two kinds of conditional fields expressable: fields which
49+
are only present if another field is present, or fields only present
50+
if another field has certain values.
51+
52+
To add conditional fields:
53+
54+
1. Do *not* mention them in the main "properties" section.
55+
2. Set `"additionalProperties": true` for the main "properties" section.
56+
3. Add an `"allOf": [` array at the same height as `"properties"'`. Inside
57+
this place one `if`/`then` for each conditional field.
58+
4. If a field simply requires another field to be present, use the pattern
59+
`"required": [ "field" ]` inside the "if".
60+
5. If a field requires another field value, use the pattern
61+
`"properties": { "field": { "enum": [ "val1", "val2" ] } }` inside
62+
the "if".
63+
6. Inside the "then", use `"additionalProperties": false` and place
64+
empty `{}` for all the other possible properties.
65+
7. If you haven't covered all the possibilties with `if` statements,
66+
add an `else` with `"additionalProperties": false` which simply
67+
mentions every allowable property. This ensures that the fields
68+
can *only* be present when conditions are met.
69+
70+
### JSON Drinking Game!
71+
72+
1. Sip whenever you have an additional comma at the end of a sequence.
73+
2. Sip whenever you omit a comma in a sequence because you cut & paste.
74+
3. Skull whenever you wish JSON had comments.
75+
76+
Good luck!
77+
Rusty.

0 commit comments

Comments
 (0)