Skip to content

Commit 7d48c4e

Browse files
committedJul 25, 2024
add docs for new [Id] attribute and external refs
1 parent b53a420 commit 7d48c4e

File tree

1 file changed

+99
-24
lines changed

1 file changed

+99
-24
lines changed
 

‎_docs/schema/schemagen/schema-generation.md

Lines changed: 99 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,36 +36,37 @@ The above will give you a basic schema that will include the `type` keyword, and
3636
- string properties may have length requirements
3737
- numeric properties may have value range requirements
3838

39-
All of these and more are supplied via a set of attributes that can be applied to properties. The following attributes are included in this package:
39+
All of these and more are supplied via a set of attributes that can be applied to properties, and some can be applied to to types. The following attributes are included in this package:
4040

4141
- Numeric values
42-
- `Minimum`
43-
- `ExclusiveMinimum`
44-
- `Maximum`
45-
- `ExclusiveMaximum`
46-
- `MultipleOf`
42+
- `Minimum`
43+
- `ExclusiveMinimum`
44+
- `Maximum`
45+
- `ExclusiveMaximum`
46+
- `MultipleOf`
4747
- Strings
48-
- `MinLength`
49-
- `MaxLength`
50-
- `Pattern`
48+
- `MinLength`
49+
- `MaxLength`
50+
- `Pattern`
5151
- Arrays
52-
- `MinItems`
53-
- `MaxItems`
54-
- `UniqueItems`
52+
- `MinItems`
53+
- `MaxItems`
54+
- `UniqueItems`
5555
- All
56-
- `Required` & `Nullable` (see below)
57-
- `Obsolete`\* (translates to `deprecated`)
58-
- `JsonExclude`\*\*
59-
- `Title`
60-
- `Description`
61-
- `Const` \*\*\*
62-
- `Default` \*\*\*
63-
- `ReadOnly`
64-
- `WriteOnly`
56+
- `Id`
57+
- `Required` & `Nullable` (see below)
58+
- `Obsolete`\* (translates to `deprecated`)
59+
- `JsonExclude`\*\*
60+
- `Title`
61+
- `Description`
62+
- `Const` \*\*\*
63+
- `Default` \*\*\*
64+
- `ReadOnly`
65+
- `WriteOnly`
6566
- Conditional (see [Conditionals](./conditional-generation))
66-
- `If`
67-
- `Then`
68-
- `Else`
67+
- `If`
68+
- `Then`
69+
- `Else`
6970

7071
\* The `[Obsolete]` attribute is `System.Obsolete`. All of the others have been defined within this library. `System.ComponentModel.DataAnnotations` support is currently [in discussion](https://github.com/gregsdennis/json-everything/issues/143).
7172

@@ -142,6 +143,80 @@ For POCOs, read-only properties and fields will be marked with a `readOnly` keyw
142143

143144
Lastly, property names will either be listed as declared in code (default) or sorted by name. This is controlled via the `SchemaGeneratorConfiguration.PropertyOrder` property.
144145

146+
### Setting identifiers and referencing external schemas
147+
148+
In JSON Schema, the `$id` keyword is the primary way to create an identifier for a schema. To create an identifier for a .Net type, you'll use the `[Id]` attribute along with a URI. This has two effects:
149+
150+
- If the attribute is found on the root type (the type used in the `.FromType<T>()` call), then the `$id` keyword will be added to the schema.
151+
- If the attribute is found on a type used for a property, then a reference (`$ref`) will be created.
152+
153+
For example, let's look at these classes:
154+
155+
```c#
156+
[Id("https://docs.json-everything.net/foo")]
157+
class Foo
158+
{
159+
public Bar Value { get; set; }
160+
}
161+
162+
[Id("https://docs.json-everything.net/bar")]
163+
class Bar
164+
{
165+
public int Number { get; set; }
166+
}
167+
```
168+
169+
When we call `.FromType<Foo>()`, the following schema will be generated:
170+
171+
```json
172+
{
173+
"$id": "https://docs.json-everything.net/foo",
174+
"type": "object",
175+
"properties": {
176+
"Value": { "$ref": "https://docs.json-everything.net/bar" }
177+
}
178+
}
179+
```
180+
181+
Notice that the attribute on `Foo` was converted to an `$id` keyword, but the attribute on `Bar` was used in a reference.
182+
183+
Another way to apply references is through the configuration's `ExternalReferences` property. This property is a mapping that allows you to provide an `$id` URI for a given type, and can be useful for when you don't have the ability to modify a type, but you want to create a reference to it.
184+
185+
> The `ExternalReferences` configuration will override any `[Id]` attributes.
186+
{: .prompt-warning }
187+
188+
```c#
189+
var config = new SchemaGenerationConfiguration
190+
{
191+
ExternalReferences =
192+
{
193+
[typeof(DateTime)] = "https://docs.json-everything.net/date-time"
194+
}
195+
}
196+
```
197+
198+
Now when we generate a schema for
199+
200+
```c#
201+
class Person
202+
{
203+
// ...
204+
public DateTime BirthDate { get; set; }
205+
}
206+
```
207+
208+
we'll get a reference for `DateTime` instead of a schema.
209+
210+
```jsonc
211+
{
212+
"type": "object",
213+
"properties": {
214+
// ...
215+
"BirthDate": { "$ref": "https://docs.json-everything.net/date-time" }
216+
}
217+
}
218+
```
219+
145220
### XML comment support
146221

147222
In addition to the explicit attributes above, the XML comment `<Summary>` element can be configured to render to a `description` keyword. Because .Net saves this information into an external XML file instead of into the reflection data, you'll need to have a configuration object and register the XML filename.

0 commit comments

Comments
 (0)