Skip to content

Commit f8a3fe0

Browse files
committed
JSON Schema documentation
Signed-off-by: David Kral <[email protected]>
1 parent 0e309e3 commit f8a3fe0

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

docs/src/main/asciidoc/includes/attributes.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ endif::[]
243243
:tracing-javadoc-base-url: {javadoc-base-url}/io.helidon.tracing
244244
:tracing-otel-provider-javadoc-base-url: {javadoc-base-url}/io.helidon.tracing.providers.opentelemetry
245245
:types-javadoc-base-url: {javadoc-base-url}/io.helidon.common.types
246+
:json-schema-base-url: {javadoc-base-url}/io.helidon.json.schema
246247
247248
:webclient-javadoc-base-url: {javadoc-base-url}/io.helidon.webclient
248249
:webclient-api-javadoc-base-url: {javadoc-base-url}/io.helidon.webclient.api
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
///////////////////////////////////////////////////////////////////////////////
2+
3+
Copyright (c) 2025 Oracle and/or its affiliates.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
///////////////////////////////////////////////////////////////////////////////
18+
19+
= JSON Schema
20+
:description: Helidon JSON Schema
21+
:keywords: helidon, json, schema, java, se
22+
:feature-name: JSON Schema
23+
:rootdir: {docdir}/../..
24+
25+
include::{rootdir}/includes/se.adoc[]
26+
27+
== Contents
28+
29+
- <<Overview, Overview>>
30+
- <<Maven Coordinates, Maven Coordinates>>
31+
- <<Usage, Usage>>
32+
** <<Imperative Schema Creation, Imperative Schema Creation>>
33+
** <<Declarative Schema Creation, Declarative Schema Creation>>
34+
- <<Configuration, Configuration>>
35+
- <<Examples, Examples>>
36+
37+
== Overview
38+
39+
JSON Schema is a specification for describing the structure and validation rules of JSON data.
40+
It lets you define what properties are required, their types, allowed values, and more.
41+
By using JSON Schema, you can validate that incoming or outgoing JSON matches the expected contract,
42+
provide clear documentation for APIs, and enable tooling support such as code generation and
43+
auto-completion.
44+
45+
Helidon provides two complementary ways to work with JSON Schema.
46+
47+
* In the declarative approach, you describe the schema using annotations in a
48+
link:{json-schema-base-url}/io/helidon/json/schema/JsonSchema.html[`JsonSchema`] class.
49+
* In the imperative approach, you build the schema programmatically with the fluent
50+
link:{json-schema-base-url}/io/helidon/json/schema/Schema.html[`Schema`] builder API.
51+
52+
Helidon currently supports only schema generation.
53+
54+
include::{rootdir}/includes/dependencies.adoc[]
55+
56+
[source,xml]
57+
----
58+
<dependency>
59+
<groupId>io.helidon.json.schema</groupId>
60+
<artifactId>helidon-json-schema</artifactId>
61+
</dependency>
62+
----
63+
64+
== Usage
65+
66+
=== Imperative Schema Creation
67+
The entry point for each runtime JSON schema creation is a
68+
link:{json-schema-base-url}/io/helidon/json/schema/Schema.html[`Schema`] class.
69+
The imperative approach gives you full programmatic control over JSON Schema creation.
70+
Using the fluent Schema builder API, you can construct schemas step by step, configure properties,
71+
and apply constraints directly in code.
72+
This is useful when schemas need to be generated dynamically or when fine-grained customization is required.
73+
74+
[source,java]
75+
----
76+
include::{sourcedir}/se/json/JsonSchemaSnippets.java[tag=snippet_1, indent=0]
77+
----
78+
79+
Once the link:{json-schema-base-url}/io/helidon/json/schema/Schema.html[`Schema`] object is created,
80+
you can generate the JSON Schema as a String. The result looks like this:
81+
82+
[source,json]
83+
----
84+
{
85+
"$schema": "https://json-schema.org/draft/2020-12/schema",
86+
"description": "Example JSON Schema",
87+
"type": "object",
88+
"properties": {
89+
"exampleProperty": {
90+
"type": "integer",
91+
"minimum": 0
92+
}
93+
}
94+
}
95+
----
96+
97+
=== Declarative Schema Creation
98+
The declarative approach lets you define JSON Schema through annotations in a
99+
link:{json-schema-base-url}/io/helidon/json/schema/JsonSchema.html[`JsonSchema`] class.
100+
At compile time, the `helidon-json-schema-codegen` generator processes these annotations and produces a class containing the schema definition.
101+
This approach keeps your schema definitions close to your data model and ensures schemas are
102+
generated automatically without manual coding.
103+
104+
[source,java]
105+
----
106+
include::{sourcedir}/se/json/JsonSchemaSnippets.java[tag=snippet_2, indent=0]
107+
----
108+
<1> Schema defining annotation. Without this annotation the class/record will not be processed as a JSON schema
109+
110+
We will need to extend the list of annotation processors with JSON schema codegen,
111+
otherwise the annotations would not be processed:
112+
[source,xml]
113+
----
114+
<plugin>
115+
<groupId>org.apache.maven.plugins</groupId>
116+
<artifactId>maven-compiler-plugin</artifactId>
117+
<configuration>
118+
<annotationProcessorPaths>
119+
<!-- Other annotation processors -->
120+
121+
<!-- Service Registry codegen needed for automatic discovery of the generated schema -->
122+
<path>
123+
<groupId>io.helidon.service</groupId>
124+
<artifactId>helidon-service-codegen</artifactId>
125+
<version>${helidon.version}</version>
126+
</path>
127+
<!-- JSON Schema codegen -->
128+
<path>
129+
<groupId>io.helidon.json.schema</groupId>
130+
<artifactId>helidon-json-schema-codegen</artifactId>
131+
<version>${helidon.version}</version>
132+
</path>
133+
</annotationProcessorPaths>
134+
</configuration>
135+
</plugin>
136+
----
137+
138+
Once compiled, the class with the following name will be generated `ExampleSchema__JsonSchema`.
139+
This class contains the String format of the schema and is automatically discovered via ServiceRegistry.
140+
Because of that, it is possible to inject the
141+
link:{json-schema-base-url}/io/helidon/json/schema/Schema.html[`Schema`] with the
142+
link:{service-registry-base-url}/io/helidon/service/registry/Service.Named.html[`@Service.Named`] and
143+
desired class (such as `ExampleSchema.class`) as a value.
144+
145+
[source,java]
146+
----
147+
public void myMethod(@Service.Named(ExampleSchema.class) Schema schema) {
148+
//...
149+
}
150+
----
151+
152+
Or obtain it over the static `find` method on the
153+
link:{json-schema-base-url}/io/helidon/json/schema/Schema.html[`Schema`] class. This methods searches the ServiceRegistry
154+
for a Schema bound to the provided class over the parameter.
155+
156+
[source,java]
157+
----
158+
Schema.find(MyClass.class);
159+
----
160+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.helidon.docs.se.json;
2+
3+
import io.helidon.json.schema.JsonSchema;
4+
import io.helidon.json.schema.Schema;
5+
6+
class JsonSchemaSnippets {
7+
8+
void jsonSchemaProgrammaticSnippet() {
9+
// tag::snippet_1[]
10+
Schema.builder()
11+
.rootObject(builder -> builder.description("Example JSON Schema")
12+
.addIntegerProperty("exampleProperty", intBuilder -> intBuilder.minimum(0)))
13+
.build();
14+
// end::snippet_1[]
15+
}
16+
17+
// tag::snippet_2[]
18+
@JsonSchema.Schema // <1>
19+
@JsonSchema.Description("Example JSON Schema")
20+
public record ExampleSchema(@JsonSchema.Integer.Minimum(0) int exampleProperty) {
21+
}
22+
// end::snippet_2[]
23+
24+
}

0 commit comments

Comments
 (0)