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 ¶
func ExtractExamples(elements map[lowmodel.KeyReference[string]]lowmodel.ValueReference[*low.Example]) map[string]*Example
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 URL string Email string // 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 ¶
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, &lowContact) // build high highContact := NewContact(&lowContact) fmt.Print(highContact.Name)
Output: Buckaroo
type Discriminator ¶
type Discriminator struct { PropertyName string Mapping map[string]string // 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, &lowDiscriminator) // build high-level model highDiscriminator := NewDiscriminator(&lowDiscriminator) // print out a mapping defined for the discriminator. fmt.Print(highDiscriminator.Mapping["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.
type Example ¶
type Example struct { Summary string Description string Value any ExternalValue string Extensions map[string]any // 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 ¶
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, &lowExample) // build out low-level example _ = lowExample.Build(node.Content[0], nil) // create a new high-level example highExample := NewExample(&lowExample) fmt.Print(highExample.ExternalValue)
Output: https://pb33f.io
type ExternalDoc ¶
type ExternalDoc struct { Description string URL string Extensions map[string]any // 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.
Example ¶
// create a new external documentation spec reference // this can be YAML or JSON. yml := `description: hack code docs url: https://pb33f.io/docs x-hack: code` // unmarshal the raw bytes into a *yaml.Node var node yaml.Node _ = yaml.Unmarshal([]byte(yml), &node) // build low-level ExternalDoc var lowExt lowbase.ExternalDoc _ = lowmodel.BuildModel(&node, &lowExt) // build out low-level properties (like extensions) _ = lowExt.Build(node.Content[0], nil) // create new high-level ExternalDoc highExt := NewExternalDoc(&lowExt) // print out a extension fmt.Print(highExt.Extensions["x-hack"])
Output: code
func (*ExternalDoc) GoLow ¶
func (e *ExternalDoc) GoLow() *low.ExternalDoc
GoLow returns the low-level ExternalDoc instance used to create the high-level one.
type Info ¶
type Info struct { Title string Description string TermsOfService string Contact *Contact License *License Version string Extensions map[string]any // 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 ¶
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 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(node.Content[0], nil) // build the high level model highInfo := NewInfo(&lowInfo) // print out the contact name. fmt.Print(highInfo.Contact.Name)
Output: buckaroo
type License ¶
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 ¶
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, &lowLicense) _ = lowLicense.Build(node.Content[0], nil) // build the high level model highLicense := NewLicense(&lowLicense) // print out the contact name. fmt.Print(highLicense.Name)
Output: MIT
type Schema ¶
type Schema struct { // 3.1 only, used to define a dialect for this schema, label is '$schema'. SchemaTypeRef string // In versions 2 and 3.0, this ExclusiveMaximum can only be a boolean. ExclusiveMaximumBool *bool // In version 3.1, ExclusiveMaximum is an integer. ExclusiveMaximum *int64 // In versions 2 and 3.0, this ExclusiveMinimum can only be a boolean. ExclusiveMinimum *int64 // In version 3.1, ExclusiveMinimum is an integer. ExclusiveMinimumBool *bool // 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 // Schemas are resolved on demand using a SchemaProxy AllOf []*SchemaProxy // Polymorphic Schemas are only available in version 3+ OneOf []*SchemaProxy AnyOf []*SchemaProxy Discriminator *Discriminator // in 3.1 examples can be an array (which is recommended) Examples []any // Compatible with all versions Not []*SchemaProxy Items []*SchemaProxy Properties map[string]*SchemaProxy Title string MultipleOf *int64 Maximum *int64 Minimum *int64 MaxLength *int64 MinLength *int64 Pattern string Format string MaxItems *int64 MinItems *int64 UniqueItems *int64 MaxProperties *int64 MinProperties *int64 Required []string Enum []any AdditionalProperties any Description string Default any Nullable *bool ReadOnly *bool WriteOnly *bool XML *XML ExternalDocs *ExternalDoc Example any Deprecated *bool Extensions map[string]any // 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.
- v2 schema: https://swagger.io/specification/v2/#schemaObject
- v3 schema: https://swagger.io/specification/#schema-object
- v3.1 schema: https://spec.openapis.org/oas/v3.1.0#schema-object
func NewSchema ¶
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, &lowSchema) _ = lowSchema.Build(node.Content[0], nil) // build the high level model highSchema := NewSchema(&lowSchema) // print out the description of 'aProperty' fmt.Print(highSchema.Properties["aProperty"].Schema().Description)
Output: this is an integer property
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 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, &lowSchema) _ = lowSchema.Build(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["aProperty"].Schema().Description)
Output: this is an integer property
func (*SchemaProxy) GetBuildError ¶
func (sp *SchemaProxy) GetBuildError() error
GetBuildError returns any error that was thrown when calling Schema()
func (*SchemaProxy) GoLow ¶ added in v0.1.6
func (sp *SchemaProxy) GoLow() *base.SchemaProxy
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 Tag ¶
type Tag struct { Name string Description string ExternalDocs *ExternalDoc Extensions map[string]any // 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 ¶
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, &lowTag) _ = lowTag.Build(node.Content[0], nil) // build the high level tag highTag := NewTag(&lowTag) // print out the tag name fmt.Print(highTag.Name)
Output: Purchases
type XML ¶
type XML struct { Name string Namespace string Prefix string Attribute bool Wrapped bool Extensions map[string]any // 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 ¶
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 prefix: sample` // 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, &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