Skip to content

Latest commit

 

History

History
17 lines (16 loc) · 4.79 KB

File metadata and controls

17 lines (16 loc) · 4.79 KB

Architecture

  • encoding/json/v2 (encoding/json/jsontext) — stable in Go 1.27 standard library.
  • refOrValue[T, O] (ref.go) — generic type backing the *Ref aliases of every object but Schema (HeaderRef, ResponseRef, etc.). Implements custom UnmarshalJSONFrom / MarshalJSONTo. Probes for $ref by attempting to unmarshal as Reference; falls back to the value type if $ref is absent.
  • loader (loader.go) — two-pass load: unmarshal → collectResolveRefs (collect component schemas, then resolve all $refs).
  • Schema.Ref is the JSON Schema $ref keyword, as OAS 3.1 defines it: a schema that refers to another is a *Schema like any other, so it can carry sibling keywords (deprecated, description, …), which apply in addition to the target, and a component schema can be just a reference. SchemaRef holds the $ref's Identifier and, once loaded, its target as Value; nothing follows it recursively. $ref is written after the keywords beside it.
  • A schema's place in components.schemas or an object's properties is kept on the Schema itself, so a whole-struct assignment *s = *v moves s to wherever v was. Schema.Replace copies v into s and keeps s's place.
  • Schema cycles (schema_cycle.go): a schema may lead back to itself through properties, items or additionalProperties, since each step descends into the value, which is how a tree or a list is described. A cycle through $ref, allOf, anyOf, oneOf or not alone never descends, and JSON Schema leaves it undefined, so the loader rejects it and names the cycle. A document built in code is not checked; code that follows Ref.Value should keep a visited set, as derefType does.
  • Discriminator.Mapping maps payload values to component schemas, each written as a bare name or a reference; MappingRef turns either into a reference. The loader checks every value resolves, but keeps it as written, so code that renames or redirects a schema must rewrite mapping values as well as Schema.Ref. A discriminator needs oneOf, anyOf or allOf beside it, except on a component schema that another component extends through allOf, the parent the specification allows it on; Components.Validate knows which those are and passes it to each schema's validation.
  • Schema.PropertyNames is a schema like Items: walkers that visit every schema should visit it too. It constrains an object's keys, not the object itself, so it is not part of the cycle check.
  • Unknown schema keywords fail validation. A keyword the library does not model lands in Extensions on load, and Validate rejects anything there without an x- prefix, so an unsupported keyword is reported instead of being carried along unseen.
  • Schema.Enum is []jsontext.Value, Schema.Const and Schema.Default are jsontext.Value — raw JSON is preserved exactly as written. Kind-based validation (enumKindMatchesType, isJSONInteger) checks types without decoding to Go values.
  • Schema (un)marshalling (schema_json.go) — decodes through schemaJSON, whose shallower type field overrides the embedded one: a type of [X, "null"] becomes Type X with Nullable set. An array of several non-null types fails to decode.
  • Schema.Type is optional (JSON Schema 2020-12): without it a schema constrains no type, and the empty schema accepts any value. Keywords tied to one type (properties, items, format, pattern, …) are allowed without it, each applying only to instances of its type (JSON Schema 2020-12 core, §7.6.1), and are still validated; Validate rejects them only where they contradict an explicit type. Without a type, required may name properties the schema does not declare, as in an anyOf branch that only demands a key. An array needs no items: without it, any items are allowed, which is how an array only ever seen empty is described (maxItems: 0).
  • Schema.AdditionalProperties is *AdditionalProperties: a schema for the extra properties' values, or a bare boolean. A nil pointer means the keyword is absent, which is not the same as true downstream.
  • Patterns (pattern.go) are compiled with Go's regexp (RE2). jsonOpts translates ECMA-262 escapes RE2 spells differently on load, and back on write, so a pattern round-trips as written. Marshalling without jsonOpts writes the RE2 form.
  • Empty values — a list or map whose empty value means the same as its absence, or is invalid, is omitempty, so code that empties one writes nothing. One whose empty value means something is omitzero and written whenever it is non-nil: security (no requirements), enum (no valid value), paths and webhooks (count towards the required "at least one of"), and path-item and operation servers (an override the specification does not define as empty).