Documentation
¶
Overview ¶
Package jsonschema uses reflection to generate JSON Schemas from Go types [1].
If json tags are present on struct fields, they will be used to infer property names and if a property is required (omitempty is present).
[1] http://json-schema.org/latest/json-schema-validation.html
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // TrueSchema defines a schema with a true value TrueSchema = &Schema{boolean: &[]bool{true}[0]} // FalseSchema defines a schema with a false value FalseSchema = &Schema{boolean: &[]bool{false}[0]} )
var Version = "https://json-schema.org/draft/2020-12/schema"
Version is the JSON Schema version.
Functions ¶
func NewProperties ¶
func NewProperties() *orderedmap.OrderedMap[string, *Schema]
NewProperties is a helper method to instantiate a new properties ordered map.
func ToSnakeCase ¶
ToSnakeCase converts the provided string into snake case using dashes. This is useful for Schema IDs and definitions to be coherent with common JSON Schema examples.
Types ¶
type CommentOption ¶
type CommentOption func(*commentOptions)
CommentOption allows for special configuration options when preparing Go source files for comment extraction.
func WithFullComment ¶
func WithFullComment() CommentOption
WithFullComment will configure the comment extraction to process to use an object type's full comment text instead of just the synopsis.
type Definitions ¶
Definitions hold schema definitions. http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.26 RFC draft-wright-json-schema-validation-00, section 5.26
type ID ¶
type ID string
ID represents a Schema ID type which should always be a URI. See draft-bhutton-json-schema-00 section 8.2.1
const EmptyID ID = ""
EmptyID is used to explicitly define an ID with no value.
func (ID) Add ¶
Add appends the provided path to the id, and removes any anchor data that might be there.
type Reflector ¶
type Reflector struct {
// BaseSchemaID defines the URI that will be used as a base to determine Schema
// IDs for models. For example, a base Schema ID of `https://eino-contrib.com/schemas`
// when defined with a struct called `User{}`, will result in a schema with an
// ID set to `https://eino-contrib.com/schemas/user`.
//
// If no `BaseSchemaID` is provided, we'll take the type's complete package path
// and use that as a base instead. Set `Anonymous` to try if you do not want to
// include a schema ID.
BaseSchemaID ID
// Anonymous when true will hide the auto-generated Schema ID and provide what is
// known as an "anonymous schema". As a rule, this is not recommended.
Anonymous bool
// AssignAnchor when true will use the original struct's name as an anchor inside
// every definition, including the root schema. These can be useful for having a
// reference to the original struct's name in CamelCase instead of the snake-case used
// by default for URI compatibility.
//
// Anchors do not appear to be widely used out in the wild, so at this time the
// anchors themselves will not be used inside generated schema.
AssignAnchor bool
// AllowAdditionalProperties will cause the Reflector to generate a schema
// without additionalProperties set to 'false' for all struct types. This means
// the presence of additional keys in JSON objects will not cause validation
// to fail. Note said additional keys will simply be dropped when the
// validated JSON is unmarshaled.
AllowAdditionalProperties bool
// RequiredFromJSONSchemaTags will cause the Reflector to generate a schema
// that requires any key tagged with `jsonschema:required`, overriding the
// default of requiring any key *not* tagged with `json:,omitempty`.
RequiredFromJSONSchemaTags bool
// Do not reference definitions. This will remove the top-level $defs map and
// instead cause the entire structure of types to be output in one tree. The
// list of type definitions (`$defs`) will not be included.
DoNotReference bool
// ExpandedStruct when true will include the reflected type's definition in the
// root as opposed to a definition with a reference.
ExpandedStruct bool
// FieldNameTag will change the tag used to get field names. json tags are used by default.
FieldNameTag string
// IgnoredTypes defines a slice of types that should be ignored in the schema,
// switching to just allowing additional properties instead.
IgnoredTypes []any
// Lookup allows a function to be defined that will provide a custom mapping of
// types to Schema IDs. This allows existing schema documents to be referenced
// by their ID instead of being embedded into the current schema definitions.
// Reflected types will never be pointers, only underlying elements.
Lookup func(reflect.Type) ID
// Mapper is a function that can be used to map custom Go types to jsonschema schemas.
Mapper func(reflect.Type) *Schema
// SchemaModifier allows modification of the generated JSON schema.
SchemaModifier SchemaModifierFn
// Namer allows customizing of type names. The default is to use the type's name
// provided by the reflect package.
Namer func(reflect.Type) string
// KeyNamer allows customizing of key names.
// The default is to use the key's name as is, or the json tag if present.
// If a json tag is present, KeyNamer will receive the tag's name as an argument, not the original key name.
KeyNamer func(string) string
// AdditionalFields allows adding structfields for a given type
AdditionalFields func(reflect.Type) []reflect.StructField
// LookupComment allows customizing comment lookup. Given a reflect.Type and optionally
// a field name, it should return the comment string associated with this type or field.
//
// If the field name is empty, it should return the type's comment; otherwise, the field's
// comment should be returned. If no comment is found, an empty string should be returned.
//
// When set, this function is called before the below CommentMap lookup mechanism. However,
// if it returns an empty string, the CommentMap is still consulted.
LookupComment func(reflect.Type, string) string
// CommentMap is a dictionary of fully qualified go types and fields to comment
// strings that will be used if a description has not already been provided in
// the tags. Types and fields are added to the package path using "." as a
// separator.
//
// Type descriptions should be defined like:
//
// map[string]string{"github.com/eino-contrib/jsonschema.Reflector": "A Reflector reflects values into a Schema."}
//
// And Fields defined as:
//
// map[string]string{"github.com/eino-contrib/jsonschema.Reflector.DoNotReference": "Do not reference definitions."}
//
// See also: AddGoComments, LookupComment
CommentMap map[string]string
}
A Reflector reflects values into a Schema.
func (*Reflector) AddGoComments ¶
func (r *Reflector) AddGoComments(base, path string, opts ...CommentOption) error
AddGoComments will update the reflectors comment map with all the comments found in the provided source directories including sub-directories, in order to generate a dictionary of comments associated with Types and Fields. The results will be added to the `Reflect.CommentMap` ready to use with Schema "description" fields.
The `go/parser` library is used to extract all the comments and unfortunately doesn't have a built-in way to determine the fully qualified name of a package. The `base` parameter, the URL used to import that package, is thus required to be able to match reflected types.
When parsing type comments, by default we use the `go/doc`'s Synopsis method to extract the first phrase only. Field comments, which tend to be much shorter, will include everything. This behavior can be changed by using the `WithFullComment` option.
func (*Reflector) ReflectFromType ¶
ReflectFromType generates root schema
func (*Reflector) SetBaseSchemaID ¶
SetBaseSchemaID is a helper use to be able to set the reflectors base schema ID from a string as opposed to then ID instance.
type Schema ¶
type Schema struct {
// RFC draft-bhutton-json-schema-00
Version string `json:"$schema,omitempty"` // section 8.1.1
ID ID `json:"$id,omitempty"` // section 8.2.1
Anchor string `json:"$anchor,omitempty"` // section 8.2.2
Ref string `json:"$ref,omitempty"` // section 8.2.3.1
DynamicRef string `json:"$dynamicRef,omitempty"` // section 8.2.3.2
Definitions Definitions `json:"$defs,omitempty"` // section 8.2.4
Comments string `json:"$comment,omitempty"` // section 8.3
// RFC draft-bhutton-json-schema-00 section 10.2.1 (Sub-schemas with logic)
AllOf []*Schema `json:"allOf,omitempty"` // section 10.2.1.1
AnyOf []*Schema `json:"anyOf,omitempty"` // section 10.2.1.2
OneOf []*Schema `json:"oneOf,omitempty"` // section 10.2.1.3
Not *Schema `json:"not,omitempty"` // section 10.2.1.4
// RFC draft-bhutton-json-schema-00 section 10.2.2 (Apply sub-schemas conditionally)
If *Schema `json:"if,omitempty"` // section 10.2.2.1
Then *Schema `json:"then,omitempty"` // section 10.2.2.2
Else *Schema `json:"else,omitempty"` // section 10.2.2.3
DependentSchemas map[string]*Schema `json:"dependentSchemas,omitempty"` // section 10.2.2.4
// RFC draft-bhutton-json-schema-00 section 10.3.1 (arrays)
PrefixItems []*Schema `json:"prefixItems,omitempty"` // section 10.3.1.1
Items *Schema `json:"items,omitempty"` // section 10.3.1.2 (replaces additionalItems)
Contains *Schema `json:"contains,omitempty"` // section 10.3.1.3
// RFC draft-bhutton-json-schema-00 section 10.3.2 (sub-schemas)
Properties *orderedmap.OrderedMap[string, *Schema] `json:"properties,omitempty"` // section 10.3.2.1
PatternProperties map[string]*Schema `json:"patternProperties,omitempty"` // section 10.3.2.2
AdditionalProperties *Schema `json:"additionalProperties,omitempty"` // section 10.3.2.3
PropertyNames *Schema `json:"propertyNames,omitempty"` // section 10.3.2.4
// Type is the instance data model type (RFC draft-bhutton-json-schema-validation-00, section 6).
// The keyword in JSON Schema is "type".
Type string `json:"-"` // section 6.1.1
// TypeEnhanced is an enhanced description of the instance data model type (RFC draft-bhutton-json-schema-validation-00, section 6).
// The keyword in JSON Schema is "type".
// In most cases, you won't need it.
// You can only set one of Type and TypeEnhanced.
// When marshalling to JSON Schema string, if TypeEnhanced is not nil, the `type` keyword will be of type Array<String>.
// When unmarshalling from JSON Schema string, if the `type` keyword is of type Array<String>, it will be unmarshalled into the TypeEnhanced field.
// Optional.
TypeEnhanced []string `json:"-"` // section 6.1.1
Enum []any `json:"enum,omitempty"` // section 6.1.2
Const any `json:"const,omitempty"` // section 6.1.3
MultipleOf json.Number `json:"multipleOf,omitempty"` // section 6.2.1
Maximum json.Number `json:"maximum,omitempty"` // section 6.2.2
ExclusiveMaximum json.Number `json:"exclusiveMaximum,omitempty"` // section 6.2.3
Minimum json.Number `json:"minimum,omitempty"` // section 6.2.4
ExclusiveMinimum json.Number `json:"exclusiveMinimum,omitempty"` // section 6.2.5
MaxLength *uint64 `json:"maxLength,omitempty"` // section 6.3.1
MinLength *uint64 `json:"minLength,omitempty"` // section 6.3.2
Pattern string `json:"pattern,omitempty"` // section 6.3.3
MaxItems *uint64 `json:"maxItems,omitempty"` // section 6.4.1
MinItems *uint64 `json:"minItems,omitempty"` // section 6.4.2
UniqueItems bool `json:"uniqueItems,omitempty"` // section 6.4.3
MaxContains *uint64 `json:"maxContains,omitempty"` // section 6.4.4
MinContains *uint64 `json:"minContains,omitempty"` // section 6.4.5
MaxProperties *uint64 `json:"maxProperties,omitempty"` // section 6.5.1
MinProperties *uint64 `json:"minProperties,omitempty"` // section 6.5.2
Required []string `json:"required,omitempty"` // section 6.5.3
DependentRequired map[string][]string `json:"dependentRequired,omitempty"` // section 6.5.4
// RFC draft-bhutton-json-schema-validation-00, section 7
Format string `json:"format,omitempty"`
// RFC draft-bhutton-json-schema-validation-00, section 8
ContentEncoding string `json:"contentEncoding,omitempty"` // section 8.3
ContentMediaType string `json:"contentMediaType,omitempty"` // section 8.4
ContentSchema *Schema `json:"contentSchema,omitempty"` // section 8.5
// RFC draft-bhutton-json-schema-validation-00, section 9
Title string `json:"title,omitempty"` // section 9.1
Description string `json:"description,omitempty"` // section 9.1
Default any `json:"default,omitempty"` // section 9.2
Deprecated bool `json:"deprecated,omitempty"` // section 9.3
ReadOnly bool `json:"readOnly,omitempty"` // section 9.4
WriteOnly bool `json:"writeOnly,omitempty"` // section 9.4
Examples []any `json:"examples,omitempty"` // section 9.5
Extras map[string]any `json:"-"`
// contains filtered or unexported fields
}
Schema represents a JSON Schema object type. RFC draft-bhutton-json-schema-00 section 4.3
func ReflectFromType ¶
ReflectFromType generates root schema using the default Reflector
func (*Schema) MarshalJSON ¶
MarshalJSON is used to serialize a schema object or boolean.
func (*Schema) UnmarshalJSON ¶
UnmarshalJSON is used to parse a schema object or boolean.
type SchemaModifierFn ¶ added in v1.0.1
type SchemaModifierFn func(jsonTagName string, t reflect.Type, tag reflect.StructTag, schema *Schema)
SchemaModifierFn is a callback function that will be called after the schema is generated. This allows you to modify the schema dynamically. NOTE: `jsonTagName` will be "_root" for the top level object, and `tag` will be "".