Introduction
This issue defines the JSON schema exporting APIs largely following the design of the stj-schema-mapper prototype. Rather than introducing a JSON schema exchange type, the proposed exporter methods generate schema documents represented as JsonNode instances which can be modified or mapped to other schema models as required.
The exporter employs a callback model allowing users to enrich the generated schema for every node in the generated type graph using metadata from arbitrary attribute annotations.
Contributes to #100159
API Proposal
namespaceSystem.Text.Json.Schema;// New namespacepublicstaticclassJsonSchemaExporter{publicstaticJsonNodeGetJsonSchemaAsNode(thisJsonSerializerOptionsoptions,Typetype,JsonSchemaExporterOptions?exporterOptions=null);publicstaticJsonNodeGetJsonSchemaAsNode(thisJsonTypeInfotypeInfo,JsonSchemaExporterOptions?exporterOptions=null);}publicsealedclassJsonSchemaExporterOptions{/// The default options singleton.publicstaticJsonSchemaExporterOptionsDefault{get;}=new();/// Determines whether schema references should be generated for recurring schema nodes.publicboolAllowSchemaReferences{get;init;}=true;/// Determines the compatibility mode used by the exporter.publicJsonSchemaExporterCompatibilityModeCompatibilityMode{get;init;}=JsonSchemaExporterCompatibilityMode.Strict;/// Defines a callback that is invoked for every schema that is generated within the type graph.publicAction<JsonSchemaExporterContext,JsonObject>?OnSchemaNodeGenerated{get;init;}}/// Context of the current schema node being generated.publicreadonlystructJsonSchemaExporterContext{/// The parent collection type if the schema is being generated for a collection element or dictionary value.publicReadOnlySpan<string>Path{get;}/// The JsonTypeInfo for the type being processed.publicJsonTypeInfoTypeInfo{get;}/// The JsonPropertyInfo if the schema is being generated for a property.publicJsonPropertyInfo?PropertyInfo{get;}}publicenumJsonSchemaExporterCompatibilityMode{/// Generates schemas that are strict with respect to nullability annotations and constructor parameter requiredness.Strict=0,/// Generates schemas that are more permissive but preserve compatibility with the specified JsonSerializerOptions.JsonSerializer=1,}API Usage
Here's an example using the callback API to extract schema information from other attributes:
varoptions=newJsonSchemaExporterOptions{OnSchemaNodeGenerated=static(ctx,schema)=>{DescriptionAttribute?descriptionAttribute=ctx.PropertyInfo?.AttributeProvider?.GetCustomAttribute<DescriptionAttribute>();if(descriptionAttribute!=null){schema["description"]=(JsonNode)descriptionAttribute.Description;}}});JsonNodenode=JsonSerializerOptions.Default.GetJsonSchemaAsNode(typeof(MyPoco),options);// { "type" : "object", "properties" : { "X" : { "type" : "integer", "description" : "This is property X" } } }publicclassMyPoco{[Description("This is property X")]publicintX{get;set;}}cc @captainsafia@stephentoub@gregsdennis
Introduction
This issue defines the JSON schema exporting APIs largely following the design of the stj-schema-mapper prototype. Rather than introducing a JSON schema exchange type, the proposed exporter methods generate schema documents represented as
JsonNodeinstances which can be modified or mapped to other schema models as required.The exporter employs a callback model allowing users to enrich the generated schema for every node in the generated type graph using metadata from arbitrary attribute annotations.
Contributes to #100159
API Proposal
API Usage
Here's an example using the callback API to extract schema information from other attributes:
cc @captainsafia@stephentoub@gregsdennis