Skip to content

Commit 6e0d037

Browse files
authored
Merge pull request #5 from gregsdennis/schema/codegen
Schema/codegen
2 parents 80e0f2c + 8b8182b commit 6e0d037

11 files changed

+213
-8
lines changed

_docs/schema/codegen/close.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: __close
3+
close: true
4+
permalink: /schema/codegen/:title/
5+
order: "1.6.9"
6+
---
+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
layout: page
3+
title: Generating Code from JSON Schema
4+
bookmark: Basics
5+
permalink: /schema/:title/
6+
icon: fas fa-tag
7+
order: "1.6.1"
8+
---
9+
*JsonSchema.Net.CodeGeneration* is a tool that can create C# code from JSON Schemas.
10+
11+
For example, given the schema:
12+
13+
```json
14+
{
15+
"title": "MyObject",
16+
"type": "object",
17+
"properties": {
18+
"Foo": { "type": "string" }
19+
}
20+
}
21+
```
22+
23+
it can generate a C# class like
24+
25+
```c#
26+
public class MyObject
27+
{
28+
public string Foo { get; set; }
29+
}
30+
```
31+
32+
## Capabilities {#schema-codegen-capabilities}
33+
34+
The code generation is currently quite basic. It will generate types for simple custom objects and any named array or dictionary type.
35+
36+
`$ref` is generally supported, even for recursive models like linked lists and binary trees, however there is no loop detection, so if you do something like this:
37+
38+
```json
39+
{
40+
"$ref": "#"
41+
}
42+
```
43+
44+
you'll just get a stack overflow exception. That's on you. Don't do that.
45+
46+
### Built-in types
47+
48+
Built-in types, like strings and arrays, are supported by reference only. These generally will not have type declarations generated for them, however they can appear as types used within other declarations. For example, `string` in the example above is used for the `Foo` property, but there isn't a `string` type declaration included in the output because the type is built-in.
49+
50+
There is an exception to this behavior for arrays and dictionaries, which is explained [below](#including-a-name).
51+
52+
## Usage
53+
54+
There is currently limited support for translating JSON Schema into code. However there is ongoing discussion for an official [JSON Schema code generation vocabulary](https://github.com/json-schema-org/vocab-idl). Please feel free to read up and join in on the effort there.
55+
56+
Currently, the class name is derived from the `title` keyword. There is an open issue in the repository above to discuss using this keyword. It's currently leaning toward the vocabulary defining a custom keyword, but as nothing has been decided yet, `title` is used here for now.
57+
58+
### Custom objects
59+
60+
Generating for custom objects is the real power behind code generation. Being able to read a schema produced by some other developer (e.g. from an OpenAPI document) and automatically create types can save developers a lot of time.
61+
62+
This library generates custom types for schemas that declare an `object` type and include `title` and `properties` without `additionalProperties`. It will also automatically generate types found nested in the schema. For example
63+
64+
```json
65+
{
66+
"title": "MyCustomObject",
67+
"type": "object",
68+
"properties": {
69+
"Foo": { "type": "string" },
70+
"Bar": {
71+
"title": "Bar",
72+
"type": "object",
73+
"properties": {
74+
"Baz": { "type": "integer" }
75+
}
76+
}
77+
}
78+
}
79+
```
80+
81+
generates
82+
83+
```c#
84+
public class MyCustomObject
85+
{
86+
public string Foo { get; set; }
87+
public Bar Bar { get; set; }
88+
}
89+
90+
public class Bar
91+
{
92+
public int Baz { get; set; }
93+
}
94+
```
95+
96+
There is some basic duplicate definition detection that serves two purposes:
97+
98+
1. It avoids creating multiple declarations for the same type. For example, if `Foo` had `Bar1` and `Bar2` properties, only one `Bar` declaration would be generated. Ideally this kind of duplication should be defined in the schema using a `$ref`.
99+
2. It prevents creating multiple types with the same name. For example, if there are two subschemas with the same name that define two different types, an exception would be thrown indicating the name re-use.
100+
101+
For type and property naming, some basic string transformation occurs:
102+
103+
| Original | Transformed |
104+
|:-|:-|
105+
| `kebab-case` | `KebabCase` |
106+
| `snake_case` | `SnakeCase` |
107+
| `spaced words` |`SpacedWords` |
108+
| `words-with-2-numbers` | `WordsWith2Numbers` |
109+
| `just-a-letter` | `JustALetter` |
110+
111+
Anything other conventions will likely result in undesirable code output or an exception.
112+
113+
### Arrays
114+
115+
When a schema declares an `array` type and includes an `items` keyword (in the single schema form, not an array of schemas), an array is used.
116+
117+
```json
118+
{
119+
"type": "array",
120+
"items": {
121+
"type": "integer"
122+
}
123+
}
124+
```
125+
126+
produces no declaration, but using this schema (e.g. to define object properties) appears as
127+
128+
```c#
129+
int[]
130+
```
131+
132+
### Dictionaries
133+
134+
When a schema declares an `object` type and only includes `additionalProperties` without `properties`, this models a dictionary.
135+
136+
```json
137+
{
138+
"title": "MyIntDictionary",
139+
"type": "object",
140+
"additionalProperties": {
141+
"type": "integer"
142+
}
143+
}
144+
```
145+
146+
This also produces no declaration, but using the schema appears as
147+
148+
```c#
149+
Dictionary<string, int>
150+
```
151+
152+
### Including a name on basic types {#including-a-name}
153+
154+
When you have an array or dictionary schema with a `title` keyword
155+
156+
```json
157+
{
158+
"title": "MyIntArray",
159+
"type": "array",
160+
"items": {
161+
"type": "integer"
162+
}
163+
}
164+
```
165+
166+
or
167+
168+
```json
169+
{
170+
"title": "MyIntDictionary",
171+
"type": "object",
172+
"additionalProperties": {
173+
"type": "integer"
174+
}
175+
}
176+
```
177+
178+
you now get a type declaration inheriting from `List<T>`
179+
180+
```c#
181+
public class MyIntArray : List<int> {}
182+
```
183+
184+
and `Dictionary<TKey, TValue>`
185+
186+
```c#
187+
public class MyIntDictionary : Dictionary<string, int> {}
188+
```
189+
190+
and usages will correctly appear as `MyIntArray` and `MyIntDictionary`, respectively.
191+
192+
Other basic types (e.g. strings) will ignore the `title` keyword as these types cannot be inherited.

_docs/schema/codegen/title.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: __title
3+
bookmark: Code Generation
4+
permalink: /schema/datagen/:title/
5+
folder: true
6+
order: "1.6"
7+
---

_docs/schema/datagen/close.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
title: __close
33
close: true
44
permalink: /schema/datagen/:title/
5-
order: "1.6.9"
5+
order: "1.7.9"
66
---

_docs/schema/datagen/schema-datagen.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Generating Sample JSON Data from a Schema
44
bookmark: Basics
55
permalink: /schema/:title/
66
icon: fas fa-tag
7-
order: "1.6.1"
7+
order: "1.7.1"
88
---
99
*JsonSchema.Net.DataGeneration* is a tool that can create JSON data instances using a JSON schema as a framework.
1010

_docs/schema/datagen/title.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ title: __title
33
bookmark: Data Generation
44
permalink: /schema/datagen/:title/
55
folder: true
6-
order: "1.6"
6+
order: "1.7"
77
---

_docs/schema/vocabs/close.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
title: __close
33
permalink: /schema/vocabs/:title/
44
close: true
5-
order: "1.7.9"
5+
order: "1.8.9"
66
---

_docs/schema/vocabs/title.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ title: __title
33
bookmark: Prebuilt Vocabularies
44
permalink: /schema/vocabs/:title/
55
folder: true
6-
order: "1.7"
6+
order: "1.8"
77
---

_docs/schema/vocabs/vocabs-data-2022.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: A Vocabulary for Accessing Data Stored in JSON
44
bookmark: data
55
permalink: /schema/vocabs/data-2022/
66
icon: fas fa-tag
7-
order: "1.7.1"
7+
order: "1.8.1"
88
---
99
## 1. Purpose {#schema-data-2022-purpose}
1010

_docs/schema/vocabs/vocabs-openapi.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: OpenAPI v3.1 Vocabulary
44
bookmark: Open API
55
permalink: /schema/vocabs/openapi/
66
icon: fas fa-tag
7-
order: "1.7.3"
7+
order: "1.8.3"
88
---
99

1010
This library adds support for the vocabularies, meta-schemas, and keywords defined by the [OpenAPI v3.1 specification](https://spec.openapis.org/oas/latest.html).

_docs/schema/vocabs/vocabs-unique-keys.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: A Vocabulary for Identifying Uniqueness of Array Items
44
bookmark: uniqueKeys
55
permalink: /schema/vocabs/uniquekeys/
66
icon: fas fa-tag
7-
order: "1.7.2"
7+
order: "1.8.2"
88
---
99
## 1. Purpose {#schema-uniquekeys-purpose}
1010

0 commit comments

Comments
 (0)