base

package
v0.16.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2024 License: MIT Imports: 11 Imported by: 48

Documentation

Overview

Package base contains shared high-level models that are used between both versions 2 and 3 of OpenAPI. These models are consistent across both specifications, except for the Schema.

OpenAPI 3 contains all the same properties that an OpenAPI 2 specification does, and more. The choice to not duplicate the schemas is to allow a graceful degradation pattern to be used. Schemas are the most complex beats, particularly when polymorphism is used. By re-using the same superset Schema across versions, we can ensure that all the latest features are collected, without damaging backwards compatibility.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractExamples

ExtractExamples will convert a low-level example map, into a high level one that is simple to navigate. no fidelity is lost, everything is still available via GoLow()

Types

type Contact

type Contact struct {
	Name  string `json:"name,omitempty" yaml:"name,omitempty"`
	URL   string `json:"url,omitempty" yaml:"url,omitempty"`
	Email string `json:"email,omitempty" yaml:"email,omitempty"`
	// contains filtered or unexported fields
}

Contact represents a high-level representation of the Contact definitions found at

v2 - https://swagger.io/specification/v2/#contactObject
v3 - https://spec.openapis.org/oas/v3.1.0#contact-object

func NewContact

func NewContact(contact *low.Contact) *Contact

NewContact will create a new Contact instance using a low-level Contact

Example
// define a Contact using yaml (or JSON, it doesn't matter)
yml := `name: Buckaroo
url: https://pb33f.io
email: buckaroo@pb33f.io`

// unmarshal yaml into a *yaml.Node instance
var cNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &cNode)

// build low
var lowContact lowbase.Contact
_ = lowmodel.BuildModel(cNode.Content[0], &lowContact)

// build high
highContact := NewContact(&lowContact)
fmt.Print(highContact.Name)
Output:

Buckaroo

func (*Contact) GoLow

func (c *Contact) GoLow() *low.Contact

GoLow returns the low level Contact object used to create the high-level one.

func (*Contact) GoLowUntyped added in v0.7.0

func (c *Contact) GoLowUntyped() any

GoLowUntyped will return the low-level Contact instance that was used to create the high-level one, with no type

func (*Contact) MarshalYAML added in v0.7.0

func (c *Contact) MarshalYAML() (interface{}, error)

func (*Contact) Render added in v0.7.0

func (c *Contact) Render() ([]byte, error)

type Discriminator

type Discriminator struct {
	PropertyName string                          `json:"propertyName,omitempty" yaml:"propertyName,omitempty"`
	Mapping      *orderedmap.Map[string, string] `json:"mapping,omitempty" yaml:"mapping,omitempty"`
	// contains filtered or unexported fields
}

Discriminator is only used by OpenAPI 3+ documents, it represents a polymorphic discriminator used for schemas

When request bodies or response payloads may be one of a number of different schemas, a discriminator object can be used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used to inform the consumer of the document of an alternative schema based on the value associated with it.

When using the discriminator, inline schemas will not be considered.

v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object

func NewDiscriminator

func NewDiscriminator(disc *low.Discriminator) *Discriminator

NewDiscriminator will create a new high-level Discriminator from a low-level one.

Example
// create a yaml representation of a discriminator (can be JSON, doesn't matter)
yml := `propertyName: coffee
mapping:
  coffee: in the morning`

// unmarshal into a *yaml.Node
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build low-level model
var lowDiscriminator lowbase.Discriminator
_ = lowmodel.BuildModel(node.Content[0], &lowDiscriminator)

// build high-level model
highDiscriminator := NewDiscriminator(&lowDiscriminator)

// print out a mapping defined for the discriminator.
fmt.Print(highDiscriminator.Mapping.GetOrZero("coffee"))
Output:

in the morning

func (*Discriminator) GoLow

func (d *Discriminator) GoLow() *low.Discriminator

GoLow returns the low-level Discriminator used to build the high-level one.

func (*Discriminator) GoLowUntyped added in v0.7.0

func (d *Discriminator) GoLowUntyped() any

GoLowUntyped will return the low-level Discriminator instance that was used to create the high-level one, with no type

func (*Discriminator) MarshalYAML added in v0.7.0

func (d *Discriminator) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the Discriminator object.

func (*Discriminator) Render added in v0.7.0

func (d *Discriminator) Render() ([]byte, error)

Render will return a YAML representation of the Discriminator object as a byte slice.

type DynamicValue added in v0.4.0

type DynamicValue[A any, B any] struct {
	N int // 0 == A, 1 == B
	A A
	B B
	// contains filtered or unexported fields
}

DynamicValue is used to hold multiple possible values for a schema property. There are two values, a left value (A) and a right value (B). The left value (A) is a 3.0 schema property value, the right value (B) is a 3.1 schema value.

OpenAPI 3.1 treats a Schema as a real JSON schema, which means some properties become incompatible, or others now support more than one primitive type or structure. The N value is a bit to make it each to know which value (A or B) is used, this prevents having to if/else on the value to determine which one is set.

func (*DynamicValue[A, B]) IsA added in v0.4.0

func (d *DynamicValue[A, B]) IsA() bool

IsA will return true if the 'A' or left value is set. (OpenAPI 3)

func (*DynamicValue[A, B]) IsB added in v0.4.0

func (d *DynamicValue[A, B]) IsB() bool

IsB will return true if the 'B' or right value is set (OpenAPI 3.1)

func (*DynamicValue[A, B]) MarshalYAML added in v0.7.0

func (d *DynamicValue[A, B]) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the DynamicValue object.

func (*DynamicValue[A, B]) MarshalYAMLInline added in v0.8.0

func (d *DynamicValue[A, B]) MarshalYAMLInline() (interface{}, error)

MarshalYAMLInline will create a ready to render YAML representation of the DynamicValue object. The references will be inlined instead of kept as references.

func (*DynamicValue[A, B]) Render added in v0.7.0

func (d *DynamicValue[A, B]) Render() ([]byte, error)

func (*DynamicValue[A, B]) RenderInline added in v0.8.0

func (d *DynamicValue[A, B]) RenderInline() ([]byte, error)

type Example

type Example struct {
	Summary       string                              `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description   string                              `json:"description,omitempty" yaml:"description,omitempty"`
	Value         *yaml.Node                          `json:"value,omitempty" yaml:"value,omitempty"`
	ExternalValue string                              `json:"externalValue,omitempty" yaml:"externalValue,omitempty"`
	Extensions    *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
	// contains filtered or unexported fields
}

Example represents a high-level Example object as defined by OpenAPI 3+

v3 - https://spec.openapis.org/oas/v3.1.0#example-object

func NewExample

func NewExample(example *low.Example) *Example

NewExample will create a new instance of an Example, using a low-level Example.

Example
// create some example yaml (or can be JSON, it does not matter)
yml := `summary: something interesting
description: something more interesting with detail
externalValue: https://pb33f.io
x-hack: code`

// unmarshal into a *yaml.Node
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build low-level example
var lowExample lowbase.Example
_ = lowmodel.BuildModel(node.Content[0], &lowExample)

// build out low-level example
_ = lowExample.Build(context.Background(), nil, node.Content[0], nil)

// create a new high-level example
highExample := NewExample(&lowExample)

fmt.Print(highExample.ExternalValue)
Output:

https://pb33f.io

func (*Example) GoLow

func (e *Example) GoLow() *low.Example

GoLow will return the low-level Example used to build the high level one.

func (*Example) GoLowUntyped added in v0.7.0

func (e *Example) GoLowUntyped() any

GoLowUntyped will return the low-level Example instance that was used to create the high-level one, with no type

func (*Example) MarshalYAML added in v0.7.0

func (e *Example) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the Example object.

func (*Example) Render added in v0.7.0

func (e *Example) Render() ([]byte, error)

Render will return a YAML representation of the Example object as a byte slice.

type ExternalDoc

type ExternalDoc struct {
	Description string                              `json:"description,omitempty" yaml:"description,omitempty"`
	URL         string                              `json:"url,omitempty" yaml:"url,omitempty"`
	Extensions  *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
	// contains filtered or unexported fields
}

ExternalDoc represents a high-level External Documentation object as defined by OpenAPI 2 and 3

Allows referencing an external resource for extended documentation.

v2 - https://swagger.io/specification/v2/#externalDocumentationObject
v3 - https://spec.openapis.org/oas/v3.1.0#external-documentation-object

func NewExternalDoc

func NewExternalDoc(extDoc *low.ExternalDoc) *ExternalDoc

NewExternalDoc will create a new high-level External Documentation object from a low-level one.

func (*ExternalDoc) GetExtensions added in v0.3.2

func (e *ExternalDoc) GetExtensions() *orderedmap.Map[string, *yaml.Node]

func (*ExternalDoc) GoLow

func (e *ExternalDoc) GoLow() *low.ExternalDoc

GoLow returns the low-level ExternalDoc instance used to create the high-level one.

func (*ExternalDoc) GoLowUntyped added in v0.7.0

func (e *ExternalDoc) GoLowUntyped() any

GoLowUntyped will return the low-level ExternalDoc instance that was used to create the high-level one, with no type

func (*ExternalDoc) MarshalYAML added in v0.7.0

func (e *ExternalDoc) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the ExternalDoc object.

func (*ExternalDoc) Render added in v0.7.0

func (e *ExternalDoc) Render() ([]byte, error)

Render will return a YAML representation of the ExternalDoc object as a byte slice.

type Info

type Info struct {
	Summary        string                              `json:"summary,omitempty" yaml:"summary,omitempty"`
	Title          string                              `json:"title,omitempty" yaml:"title,omitempty"`
	Description    string                              `json:"description,omitempty" yaml:"description,omitempty"`
	TermsOfService string                              `json:"termsOfService,omitempty" yaml:"termsOfService,omitempty"`
	Contact        *Contact                            `json:"contact,omitempty" yaml:"contact,omitempty"`
	License        *License                            `json:"license,omitempty" yaml:"license,omitempty"`
	Version        string                              `json:"version,omitempty" yaml:"version,omitempty"`
	Extensions     *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
	// contains filtered or unexported fields
}

Info represents a high-level Info object as defined by both OpenAPI 2 and OpenAPI 3.

The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.

v2 - https://swagger.io/specification/v2/#infoObject
v3 - https://spec.openapis.org/oas/v3.1.0#info-object

func NewInfo

func NewInfo(info *low.Info) *Info

NewInfo will create a new high-level Info instance from a low-level one.

Example
// create an example info object (including contact and license)
// this can be either JSON or YAML.
yml := `title: some spec by some company
summary: this is a summary
description: this is a specification, for an API, by a company.
termsOfService: https://pb33f.io/tos
contact:
  name: buckaroo
license:
  name: MIT
  url: https://opensource.org/licenses/MIT
version: 1.2.3`

// unmarshal raw bytes
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build out the low-level model
var lowInfo lowbase.Info
_ = lowmodel.BuildModel(&node, &lowInfo)
_ = lowInfo.Build(context.Background(), nil, node.Content[0], nil)

// build the high level model
highInfo := NewInfo(&lowInfo)

// print out the contact name.
fmt.Print(highInfo.Contact.Name)
Output:

buckaroo

func (*Info) GoLow

func (i *Info) GoLow() *low.Info

GoLow will return the low-level Info instance that was used to create the high-level one.

func (*Info) GoLowUntyped added in v0.7.0

func (i *Info) GoLowUntyped() any

GoLowUntyped will return the low-level Info instance that was used to create the high-level one, with no type

func (*Info) MarshalYAML added in v0.7.0

func (i *Info) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the Info object.

func (*Info) Render added in v0.7.0

func (i *Info) Render() ([]byte, error)

Render will return a YAML representation of the Info object as a byte slice.

type License

type License struct {
	Name       string `json:"name,omitempty" yaml:"name,omitempty"`
	URL        string `json:"url,omitempty" yaml:"url,omitempty"`
	Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"`
	// contains filtered or unexported fields
}

License is a high-level representation of a License object as defined by OpenAPI 2 and OpenAPI 3

v2 - https://swagger.io/specification/v2/#licenseObject
v3 - https://spec.openapis.org/oas/v3.1.0#license-object

func NewLicense

func NewLicense(license *low.License) *License

NewLicense will create a new high-level License instance from a low-level one.

Example
// create an example license object
// this can be either JSON or YAML.
yml := `name: MIT
url: https://opensource.org/licenses/MIT`

// unmarshal raw bytes
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build out the low-level model
var lowLicense lowbase.License
_ = lowmodel.BuildModel(node.Content[0], &lowLicense)
_ = lowLicense.Build(context.Background(), nil, node.Content[0], nil)

// build the high level model
highLicense := NewLicense(&lowLicense)

// print out the contact name.
fmt.Print(highLicense.Name)
Output:

MIT

func (*License) GoLow

func (l *License) GoLow() *low.License

GoLow will return the low-level License used to create the high-level one.

func (*License) GoLowUntyped added in v0.7.0

func (l *License) GoLowUntyped() any

GoLowUntyped will return the low-level License instance that was used to create the high-level one, with no type

func (*License) MarshalYAML added in v0.7.0

func (l *License) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the License object.

func (*License) Render added in v0.7.0

func (l *License) Render() ([]byte, error)

Render will return a YAML representation of the License object as a byte slice.

type Schema

type Schema struct {
	// 3.1 only, used to define a dialect for this schema, label is '$schema'.
	SchemaTypeRef string `json:"$schema,omitempty" yaml:"$schema,omitempty"`

	// In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean.
	// In version 3.1, ExclusiveMaximum is a number.
	ExclusiveMaximum *DynamicValue[bool, float64] `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`

	// In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean.
	// In version 3.1, ExclusiveMinimum is a number.
	ExclusiveMinimum *DynamicValue[bool, float64] `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`

	// In versions 2 and 3.0, this Type is a single value, so array will only ever have one value
	// in version 3.1, Type can be multiple values
	Type []string `json:"type,omitempty" yaml:"type,omitempty"`

	// Schemas are resolved on demand using a SchemaProxy
	AllOf []*SchemaProxy `json:"allOf,omitempty" yaml:"allOf,omitempty"`

	// Polymorphic Schemas are only available in version 3+
	OneOf         []*SchemaProxy `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
	AnyOf         []*SchemaProxy `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
	Discriminator *Discriminator `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`

	// in 3.1 examples can be an array (which is recommended)
	Examples []*yaml.Node `json:"examples,omitempty" yaml:"examples,omitempty"`

	// in 3.1 prefixItems provides tuple validation support.
	PrefixItems []*SchemaProxy `json:"prefixItems,omitempty" yaml:"prefixItems,omitempty"`

	// 3.1 Specific properties
	Contains          *SchemaProxy                          `json:"contains,omitempty" yaml:"contains,omitempty"`
	MinContains       *int64                                `json:"minContains,omitempty" yaml:"minContains,omitempty"`
	MaxContains       *int64                                `json:"maxContains,omitempty" yaml:"maxContains,omitempty"`
	If                *SchemaProxy                          `json:"if,omitempty" yaml:"if,omitempty"`
	Else              *SchemaProxy                          `json:"else,omitempty" yaml:"else,omitempty"`
	Then              *SchemaProxy                          `json:"then,omitempty" yaml:"then,omitempty"`
	DependentSchemas  *orderedmap.Map[string, *SchemaProxy] `json:"dependentSchemas,omitempty" yaml:"dependentSchemas,omitempty"`
	PatternProperties *orderedmap.Map[string, *SchemaProxy] `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
	PropertyNames     *SchemaProxy                          `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
	UnevaluatedItems  *SchemaProxy                          `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`

	// in 3.1 UnevaluatedProperties can be a Schema or a boolean
	// https://github.com/pb33f/libopenapi/issues/118
	UnevaluatedProperties *DynamicValue[*SchemaProxy, bool] `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`

	// in 3.1 Items can be a Schema or a boolean
	Items *DynamicValue[*SchemaProxy, bool] `json:"items,omitempty" yaml:"items,omitempty"`

	// 3.1 only, part of the JSON Schema spec provides a way to identify a sub-schema
	Anchor string `json:"$anchor,omitempty" yaml:"$anchor,omitempty"`

	// Compatible with all versions
	Not                  *SchemaProxy                          `json:"not,omitempty" yaml:"not,omitempty"`
	Properties           *orderedmap.Map[string, *SchemaProxy] `json:"properties,omitempty" yaml:"properties,omitempty"`
	Title                string                                `json:"title,omitempty" yaml:"title,omitempty"`
	MultipleOf           *float64                              `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
	Maximum              *float64                              `json:"maximum,renderZero,omitempty" yaml:"maximum,renderZero,omitempty"`
	Minimum              *float64                              `json:"minimum,renderZero,omitempty," yaml:"minimum,renderZero,omitempty"`
	MaxLength            *int64                                `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
	MinLength            *int64                                `json:"minLength,omitempty" yaml:"minLength,omitempty"`
	Pattern              string                                `json:"pattern,omitempty" yaml:"pattern,omitempty"`
	Format               string                                `json:"format,omitempty" yaml:"format,omitempty"`
	MaxItems             *int64                                `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
	MinItems             *int64                                `json:"minItems,omitempty" yaml:"minItems,omitempty"`
	UniqueItems          *bool                                 `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
	MaxProperties        *int64                                `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
	MinProperties        *int64                                `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
	Required             []string                              `json:"required,omitempty" yaml:"required,omitempty"`
	Enum                 []*yaml.Node                          `json:"enum,omitempty" yaml:"enum,omitempty"`
	AdditionalProperties *DynamicValue[*SchemaProxy, bool]     `json:"additionalProperties,renderZero,omitempty" yaml:"additionalProperties,renderZero,omitempty"`
	Description          string                                `json:"description,omitempty" yaml:"description,omitempty"`
	Default              *yaml.Node                            `json:"default,omitempty" yaml:"default,renderZero,omitempty"`
	Const                *yaml.Node                            `json:"const,omitempty" yaml:"const,renderZero,omitempty"`
	Nullable             *bool                                 `json:"nullable,omitempty" yaml:"nullable,omitempty"`
	ReadOnly             *bool                                 `json:"readOnly,renderZero,omitempty" yaml:"readOnly,renderZero,omitempty"`   // https://github.com/pb33f/libopenapi/issues/30
	WriteOnly            *bool                                 `json:"writeOnly,renderZero,omitempty" yaml:"writeOnly,renderZero,omitempty"` // https://github.com/pb33f/libopenapi/issues/30
	XML                  *XML                                  `json:"xml,omitempty" yaml:"xml,omitempty"`
	ExternalDocs         *ExternalDoc                          `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
	Example              *yaml.Node                            `json:"example,omitempty" yaml:"example,omitempty"`
	Deprecated           *bool                                 `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
	Extensions           *orderedmap.Map[string, *yaml.Node]   `json:"-" yaml:"-"`

	// Parent Proxy refers back to the low level SchemaProxy that is proxying this schema.
	ParentProxy *SchemaProxy `json:"-" yaml:"-"`
	// contains filtered or unexported fields
}

Schema represents a JSON Schema that support Swagger, OpenAPI 3 and OpenAPI 3.1

Until 3.1 OpenAPI had a strange relationship with JSON Schema. It's been a super-set/sub-set mix, which has been confusing. So, instead of building a bunch of different models, we have compressed all variations into a single model that makes it easy to support multiple spec types.

func NewSchema

func NewSchema(schema *base.Schema) *Schema

NewSchema will create a new high-level schema from a low-level one.

Example
// create an example schema object
// this can be either JSON or YAML.
yml := `
title: this is a schema
type: object
properties:
  aProperty:
    description: this is an integer property
    type: integer
    format: int64`

// unmarshal raw bytes
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build out the low-level model
var lowSchema lowbase.Schema
_ = low.BuildModel(node.Content[0], &lowSchema)
_ = lowSchema.Build(context.Background(), node.Content[0], nil)

// build the high level model
highSchema := NewSchema(&lowSchema)

// print out the description of 'aProperty'
fmt.Print(highSchema.Properties.GetOrZero("aProperty").Schema().Description)
Output:

this is an integer property

func (*Schema) GoLow

func (s *Schema) GoLow() *base.Schema

GoLow will return the low-level instance of Schema that was used to create the high level one.

func (*Schema) GoLowUntyped added in v0.7.0

func (s *Schema) GoLowUntyped() any

GoLowUntyped will return the low-level Schema instance that was used to create the high-level one, with no type

func (*Schema) MarshalJSON added in v0.16.6

func (s *Schema) MarshalJSON() ([]byte, error)

MarshalJSON will create a ready to render JSON representation of the Schema object.

func (*Schema) MarshalJSONInline added in v0.16.6

func (s *Schema) MarshalJSONInline() ([]byte, error)

MarshalJSONInline will render out the Schema pointer as JSON, and all refs will be inlined fully

func (*Schema) MarshalYAML added in v0.7.0

func (s *Schema) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the ExternalDoc object.

func (*Schema) MarshalYAMLInline added in v0.8.0

func (s *Schema) MarshalYAMLInline() (interface{}, error)

MarshalYAMLInline will render out the Schema pointer as YAML, and all refs will be inlined fully

func (*Schema) Render added in v0.7.0

func (s *Schema) Render() ([]byte, error)

Render will return a YAML representation of the Schema object as a byte slice.

func (*Schema) RenderInline added in v0.8.0

func (s *Schema) RenderInline() ([]byte, error)

RenderInline will return a YAML representation of the Schema object as a byte slice. All the $ref values will be inlined, as in resolved in place.

Make sure you don't have any circular references!

type SchemaProxy

type SchemaProxy struct {
	// contains filtered or unexported fields
}

SchemaProxy exists as a stub that will create a Schema once (and only once) the Schema() method is called. An underlying low-level SchemaProxy backs this high-level one.

Why use a Proxy design?

There are three reasons.

1. Circular References and Endless Loops.

JSON Schema allows for references to be used. This means references can loop around and create infinite recursive structures, These 'Circular references' technically mean a schema can NEVER be resolved, not without breaking the loop somewhere along the chain.

Polymorphism in the form of 'oneOf' and 'anyOf' in version 3+ only exacerbates the problem.

These circular traps can be discovered using the resolver, however it's still not enough to stop endless loops and endless goroutine spawning. A proxy design means that resolving occurs on demand and runs down a single level only. preventing any run-away loops.

2. Performance

Even without circular references, Polymorphism creates large additional resolving chains that take a long time and slow things down when building. By preventing recursion through every polymorphic item, building models is kept fast and snappy, which is desired for realtime processing of specs.

  • Q: Yeah, but, why not just use state to avoiding re-visiting seen polymorphic nodes?
  • A: It's slow, takes up memory and still has runaway potential in very, very long chains.

3. Short Circuit Errors.

Schemas are where things can get messy, mainly because the Schema standard changes between versions, and it's not actually JSONSchema until 3.1, so lots of times a bad schema will break parsing. Errors are only found when a schema is needed, so the rest of the document is parsed and ready to use.

func CreateSchemaProxy added in v0.7.0

func CreateSchemaProxy(schema *Schema) *SchemaProxy

CreateSchemaProxy will create a new high-level SchemaProxy from a high-level Schema, this acts the same as if the SchemaProxy is pre-rendered.

func CreateSchemaProxyRef added in v0.7.0

func CreateSchemaProxyRef(ref string) *SchemaProxy

CreateSchemaProxyRef will create a new high-level SchemaProxy from a reference string, this is used only when building out new models from scratch that require a reference rather than a schema implementation.

func NewSchemaProxy

func NewSchemaProxy(schema *low.NodeReference[*base.SchemaProxy]) *SchemaProxy

NewSchemaProxy creates a new high-level SchemaProxy from a low-level one.

Example
// create an example schema object
// this can be either JSON or YAML.
yml := `
title: this is a schema
type: object
properties:
  aProperty:
    description: this is an integer property
    type: integer
    format: int64`

// unmarshal raw bytes
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build out the low-level model
var lowSchema lowbase.SchemaProxy
_ = low.BuildModel(node.Content[0], &lowSchema)
_ = lowSchema.Build(context.Background(), nil, node.Content[0], nil)

// build the high level schema proxy
highSchema := NewSchemaProxy(&low.NodeReference[*lowbase.SchemaProxy]{
	Value: &lowSchema,
})

// print out the description of 'aProperty'
fmt.Print(highSchema.Schema().Properties.GetOrZero("aProperty").Schema().Description)
Output:

this is an integer property

func (*SchemaProxy) BuildSchema added in v0.3.2

func (sp *SchemaProxy) BuildSchema() (*Schema, error)

BuildSchema operates the same way as Schema, except it will return any error along with the *Schema

func (*SchemaProxy) GetBuildError

func (sp *SchemaProxy) GetBuildError() error

GetBuildError returns any error that was thrown when calling Schema()

func (*SchemaProxy) GetReference added in v0.7.0

func (sp *SchemaProxy) GetReference() string

GetReference returns the location of the $ref if this SchemaProxy is a reference to another Schema.

func (*SchemaProxy) GetReferenceNode added in v0.14.0

func (sp *SchemaProxy) GetReferenceNode() *yaml.Node

func (*SchemaProxy) GetReferenceOrigin added in v0.13.12

func (sp *SchemaProxy) GetReferenceOrigin() *index.NodeOrigin

GetReferenceOrigin returns a pointer to the index.NodeOrigin of the $ref if this SchemaProxy is a reference to another Schema. returns nil if the origin cannot be found (which, means there is a bug, and we need to fix it).

func (*SchemaProxy) GetSchemaKeyNode added in v0.14.5

func (sp *SchemaProxy) GetSchemaKeyNode() *yaml.Node

func (*SchemaProxy) GoLow added in v0.1.6

func (sp *SchemaProxy) GoLow() *base.SchemaProxy

func (*SchemaProxy) GoLowUntyped added in v0.7.0

func (sp *SchemaProxy) GoLowUntyped() any

func (*SchemaProxy) IsReference added in v0.7.0

func (sp *SchemaProxy) IsReference() bool

IsReference returns true if the SchemaProxy is a reference to another Schema.

func (*SchemaProxy) MarshalYAML added in v0.7.0

func (sp *SchemaProxy) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the SchemaProxy object.

func (*SchemaProxy) MarshalYAMLInline added in v0.8.0

func (sp *SchemaProxy) MarshalYAMLInline() (interface{}, error)

MarshalYAMLInline will create a ready to render YAML representation of the SchemaProxy object. The $ref values will be inlined instead of kept as is.

func (*SchemaProxy) Render added in v0.7.0

func (sp *SchemaProxy) Render() ([]byte, error)

Render will return a YAML representation of the Schema object as a byte slice.

func (*SchemaProxy) Schema

func (sp *SchemaProxy) Schema() *Schema

Schema will create a new Schema instance using NewSchema from the low-level SchemaProxy backing this high-level one. If there is a problem building the Schema, then this method will return nil. Use GetBuildError to gain access to that building error.

type SecurityRequirement added in v0.2.0

type SecurityRequirement struct {
	Requirements             *orderedmap.Map[string, []string] `json:"-" yaml:"-"`
	ContainsEmptyRequirement bool                              // if a requirement is empty (this means it's optional)
	// contains filtered or unexported fields
}

SecurityRequirement is a high-level representation of a Swagger / OpenAPI 3 SecurityRequirement object.

SecurityRequirement lists the required security schemes to execute this operation. The object can have multiple security schemes declared in it which are all required (that is, there is a logical AND between the schemes).

The name used for each property MUST correspond to a security scheme declared in the Security Definitions

func NewSecurityRequirement added in v0.2.0

func NewSecurityRequirement(req *base.SecurityRequirement) *SecurityRequirement

NewSecurityRequirement creates a new high-level SecurityRequirement from a low-level one.

func (*SecurityRequirement) GoLow added in v0.2.0

GoLow returns the low-level SecurityRequirement used to create the high-level one.

func (*SecurityRequirement) GoLowUntyped added in v0.7.0

func (s *SecurityRequirement) GoLowUntyped() any

GoLowUntyped will return the low-level Discriminator instance that was used to create the high-level one, with no type

func (*SecurityRequirement) MarshalYAML added in v0.7.0

func (s *SecurityRequirement) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the SecurityRequirement object.

func (*SecurityRequirement) Render added in v0.7.0

func (s *SecurityRequirement) Render() ([]byte, error)

Render will return a YAML representation of the SecurityRequirement object as a byte slice.

type Tag

type Tag struct {
	Name         string       `json:"name,omitempty" yaml:"name,omitempty"`
	Description  string       `json:"description,omitempty" yaml:"description,omitempty"`
	ExternalDocs *ExternalDoc `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
	Extensions   *orderedmap.Map[string, *yaml.Node]
	// contains filtered or unexported fields
}

Tag represents a high-level Tag instance that is backed by a low-level one.

Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.

func NewTag

func NewTag(tag *low.Tag) *Tag

NewTag creates a new high-level Tag instance that is backed by a low-level one.

Example
// create an example schema object
// this can be either JSON or YAML.
yml := `
name: Purchases
description: All kinds of purchase related operations
externalDocs:
  url: https://pb33f.io/purchases
x-hack: code`

// unmarshal raw bytes
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build out the low-level model
var lowTag lowbase.Tag
_ = lowmodel.BuildModel(node.Content[0], &lowTag)
_ = lowTag.Build(context.Background(), nil, node.Content[0], nil)

// build the high level tag
highTag := NewTag(&lowTag)

// print out the tag name
fmt.Print(highTag.Name)
Output:

Purchases

func (*Tag) GoLow

func (t *Tag) GoLow() *low.Tag

GoLow returns the low-level Tag instance used to create the high-level one.

func (*Tag) GoLowUntyped added in v0.7.0

func (t *Tag) GoLowUntyped() any

GoLowUntyped will return the low-level Tag instance that was used to create the high-level one, with no type

func (*Tag) MarshalYAML added in v0.7.0

func (t *Tag) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the Info object.

func (*Tag) MarshalYAMLInline added in v0.8.4

func (t *Tag) MarshalYAMLInline() (interface{}, error)

func (*Tag) Render added in v0.7.0

func (t *Tag) Render() ([]byte, error)

Render will return a YAML representation of the Info object as a byte slice.

func (*Tag) RenderInline added in v0.8.4

func (t *Tag) RenderInline() ([]byte, error)

Render will return a YAML representation of the Info object as a byte slice.

type XML

type XML struct {
	Name       string `json:"name,omitempty" yaml:"name,omitempty"`
	Namespace  string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
	Prefix     string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
	Attribute  bool   `json:"attribute,omitempty" yaml:"attribute,omitempty"`
	Wrapped    bool   `json:"wrapped,omitempty" yaml:"wrapped,omitempty"`
	Extensions *orderedmap.Map[string, *yaml.Node]
	// contains filtered or unexported fields
}

XML represents a high-level representation of an XML object defined by all versions of OpenAPI and backed by low-level XML object.

A metadata object that allows for more fine-tuned XML model definitions.

When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD be used to add that information. See examples for expected behavior.

v2 - https://swagger.io/specification/v2/#xmlObject
v3 - https://swagger.io/specification/#xml-object

func NewXML

func NewXML(xml *low.XML) *XML

NewXML creates a new high-level XML instance from a low-level one.

Example
// create an example schema object
// this can be either JSON or YAML.
yml := `
namespace: https://pb33f.io/schema
name: something
attribute: true
prefix: sample
wrapped: true`

// unmarshal raw bytes
var node yaml.Node
_ = yaml.Unmarshal([]byte(yml), &node)

// build out the low-level model
var lowXML lowbase.XML
_ = lowmodel.BuildModel(node.Content[0], &lowXML)
_ = lowXML.Build(node.Content[0], nil)

// build the high level tag
highXML := NewXML(&lowXML)

// print out the XML namespace
fmt.Print(highXML.Namespace)
Output:

https://pb33f.io/schema

func (*XML) GoLow

func (x *XML) GoLow() *low.XML

GoLow returns the low level XML reference used to create the high level one.

func (*XML) GoLowUntyped added in v0.7.0

func (x *XML) GoLowUntyped() any

GoLowUntyped will return the low-level XML instance that was used to create the high-level one, with no type

func (*XML) MarshalYAML added in v0.7.0

func (x *XML) MarshalYAML() (interface{}, error)

MarshalYAML will create a ready to render YAML representation of the XML object.

func (*XML) Render added in v0.7.0

func (x *XML) Render() ([]byte, error)

Render will return a YAML representation of the XML object as a byte slice.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL