Documentation
¶
Overview ¶
Package parser provides parsing for OpenAPI Specification documents.
The parser supports OAS 2.0 through OAS 3.2.0 in YAML and JSON formats. It can resolve external references ($ref), validate structure, and preserve unknown fields for forward compatibility and extension properties. The parser can load specifications from local files or remote URLs (http:// or https://).
Quick Start ¶
Parse a file using functional options:
result, err := parser.ParseWithOptions(
parser.WithFilePath("openapi.yaml"),
parser.WithValidateStructure(true),
)
if err != nil {
log.Fatal(err)
}
if len(result.Errors) > 0 {
fmt.Printf("Parse errors: %d\n", len(result.Errors))
}
Parse from a URL:
result, err := parser.ParseWithOptions(
parser.WithFilePath("https://example.com/api/openapi.yaml"),
parser.WithValidateStructure(true),
)
if err != nil {
log.Fatal(err)
}
Or create a reusable Parser instance:
p := parser.New()
p.ResolveRefs = false
result1, _ := p.Parse("api1.yaml")
result2, _ := p.Parse("https://example.com/api2.yaml")
Features and Security ¶
The parser validates operation IDs, status codes, and HTTP status codes. For external references, it prevents path traversal attacks by restricting file access to the base directory and subdirectories. Reference resolution caches up to 100 documents by default to prevent memory exhaustion.
HTTP/HTTPS $ref resolution is available via WithResolveHTTPRefs (opt-in for security). Use WithInsecureSkipVerify for self-signed certificates. HTTP responses are cached, size-limited, and protected against circular references. See the examples in example_test.go for more details.
HTTP Client Configuration ¶
By default, the parser creates an HTTP client with a 30-second timeout for fetching remote specifications. For advanced use cases, provide a custom HTTP client:
// Custom timeout for slow networks
client := &http.Client{Timeout: 60 * time.Second}
result, err := parser.ParseWithOptions(
parser.WithFilePath("https://api.example.com/openapi.yaml"),
parser.WithHTTPClient(client),
)
// Corporate proxy
proxyURL, _ := url.Parse("http://proxy.corp.internal:8080")
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
}
result, err := parser.ParseWithOptions(
parser.WithFilePath("https://internal-api.corp/spec.yaml"),
parser.WithHTTPClient(client),
)
When a custom client is provided, the InsecureSkipVerify option is ignored. Configure TLS settings directly on your client's transport instead.
Circular Reference Handling ¶
The parser resolves non-circular references normally even when circular references exist in the document. Only the circular $ref nodes themselves remain unresolved (preserving the "$ref" key); all other references are fully inlined.
Circular references are detected when:
- A $ref points to an ancestor in the current resolution path
- The resolution depth exceeds MaxRefDepth (default: 100)
When circular references are detected:
- Non-circular $ref nodes are resolved normally
- Circular $ref nodes are left unresolved (preserves the "$ref" key)
- A warning is added to result.Warnings
- The document remains valid for most operations
To check for circular reference warnings after parsing:
result, err := parser.ParseWithOptions(
parser.WithFilePath("openapi.yaml"),
parser.WithResolveRefs(true),
)
if err != nil {
log.Fatal(err)
}
for _, warning := range result.Warnings {
if strings.Contains(warning, "circular") {
fmt.Println("Document contains circular references")
}
}
Resource Limits ¶
The parser enforces configurable resource limits to prevent denial-of-service:
- MaxRefDepth: Maximum depth for nested $ref resolution (default: 100)
- MaxCachedDocuments: Maximum external documents to cache (default: 100)
- MaxFileSize: Maximum file size for external references (default: 10MB)
Configure limits using functional options:
result, err := parser.ParseWithOptions(
parser.WithFilePath("openapi.yaml"),
parser.WithMaxRefDepth(50), // Reduce max depth
parser.WithMaxCachedDocuments(200), // Allow more cached docs
parser.WithMaxFileSize(20*1024*1024), // 20MB limit
)
Order-Preserving Marshaling ¶
The parser can preserve the original field ordering from source documents, enabling deterministic output for hash-based caching and diff-friendly serialization.
Enable order preservation during parsing:
result, err := parser.ParseWithOptions(
parser.WithFilePath("openapi.yaml"),
parser.WithPreserveOrder(true),
)
Then use the ordered marshal methods:
jsonBytes, _ := result.MarshalOrderedJSON() yamlBytes, _ := result.MarshalOrderedYAML()
For indented JSON output:
indentedJSON, _ := result.MarshalOrderedJSONIndent("", " ")
Use cases for order-preserving marshaling:
- Hash-based caching where roundtrip identity matters
- Minimizing diffs when editing and re-serializing specs
- Maintaining human-friendly key ordering
- CI pipelines that compare serialized output
When PreserveOrder is not enabled, the ordered marshal methods fall back to standard marshaling, which sorts map keys alphabetically for determinism.
Check if order was preserved after parsing:
if result.HasPreservedOrder() {
// Order information is available
}
Source Naming for Pre-Parsed Documents ¶
When parsing from bytes or io.Reader (common when fetching specs from HTTP or databases), the default SourcePath is generic ("ParseBytes.yaml" or "ParseReader.yaml"). Use WithSourceName to set a meaningful identifier:
result, err := parser.ParseWithOptions(
parser.WithBytes(specData),
parser.WithSourceName("users-api"),
)
This is especially important when joining multiple pre-parsed documents, as the joiner uses SourcePath in collision reports. Without meaningful names, collision reports show unhelpful text like "ParseBytes.yaml vs ParseBytes.yaml". The joiner will emit info-level warnings for documents with generic source names.
Alternatively, you can set SourcePath directly on the ParseResult after parsing:
result, err := parser.ParseWithOptions(parser.WithBytes(specData)) result.SourcePath = "users-api"
OAS 3.2.0 Features ¶
The parser models the full set of fixed fields OAS 3.2.0 added over 3.1.1:
- OpenAPI Object: $self (OAS3Document.Self)
- Components Object: mediaTypes (Components.MediaTypes)
- Path Item Object: query, additionalOperations
- Tag Object: summary, parent, kind
- Server Object: name
- Response Object: summary
- Media Type Object: itemSchema, itemEncoding, prefixEncoding
- Encoding Object: encoding, itemEncoding, prefixEncoding
- Example Object: dataValue, serializedValue
- Security Scheme Object: deprecated, oauth2MetadataUrl
- OAuth Flows Object: deviceAuthorization
- OAuth Flow Object: deviceAuthorizationUrl
- Discriminator Object: defaultMapping
- XML Object: nodeType
- Parameter Object: in: "querystring" (ParamInQueryString)
https://spec.openapis.org/oas/v3.2.0.html
JSON Schema 2020-12 Keywords ¶
The parser supports JSON Schema Draft 2020-12 keywords for OAS 3.1+:
- unevaluatedProperties/unevaluatedItems: Strict validation (parsed as bool or *Schema)
- contentEncoding/contentMediaType/contentSchema: Encoded content validation
- prefixItems, contains, propertyNames, dependentSchemas, $defs: Advanced schema features
Array Index References ¶
JSON Pointer references support array indices per RFC 6901:
$ref: '#/paths/~1users/get/parameters/0/schema'
ParseResult Fields ¶
ParseResult includes the detected Version, OASVersion, SourceFormat (JSON or YAML), and any parsing Errors or Warnings. The Document field contains the parsed OAS2Document or OAS3Document. The SourceFormat field can be used by conversion and joining tools to preserve the original file format. See the exported ParseResult and document type fields for complete details.
Document Type Helpers ¶
ParseResult provides convenient methods for version checking and type assertion:
result, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
// Version checking
if result.IsOAS2() {
fmt.Println("This is a Swagger 2.0 document")
}
if result.IsOAS3() {
fmt.Println("This is an OAS 3.x document")
}
// Safe type assertion
if doc, ok := result.OAS3Document(); ok {
fmt.Printf("API: %s v%s\n", doc.Info.Title, doc.Info.Version)
}
if doc, ok := result.OAS2Document(); ok {
fmt.Printf("Swagger: %s v%s\n", doc.Info.Title, doc.Info.Version)
}
These helpers eliminate the need for manual type switches on the Document field.
Version-Agnostic Access ¶
For code that needs to work uniformly across OAS 2.0 and 3.x documents without version-specific type switches, use the DocumentAccessor interface:
result, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
if accessor := result.AsAccessor(); accessor != nil {
// Unified access to paths, schemas, etc.
for path := range accessor.GetPaths() {
fmt.Println("Path:", path)
}
for name := range accessor.GetSchemas() {
// Returns Definitions (2.0) or Components.Schemas (3.x)
fmt.Println("Schema:", name)
}
// Get the schema $ref prefix for this version
fmt.Println("Prefix:", accessor.SchemaRefPrefix())
}
DocumentAccessor provides methods like GetPaths, GetSchemas, GetSecuritySchemes, GetParameters, and GetResponses that automatically map to the correct location for each OAS version.
Related Packages ¶
After parsing, use these packages for additional operations:
- github.com/erraggy/oastools/validator - Validate specifications against OAS rules
- github.com/erraggy/oastools/fixer - Fix common validation errors automatically
- github.com/erraggy/oastools/converter - Convert between OAS versions (2.0 ↔ 3.x)
- github.com/erraggy/oastools/joiner - Join multiple specifications into one
- github.com/erraggy/oastools/differ - Compare specifications and detect breaking changes
- github.com/erraggy/oastools/generator - Generate Go code from specifications
- github.com/erraggy/oastools/builder - Programmatically build specifications
- github.com/erraggy/oastools/overlay - Apply overlay transformations
Example ¶
Example demonstrates basic usage of the parser to parse an OpenAPI specification file.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
p := parser.New()
result, err := p.Parse("../testdata/petstore-3.0.yaml")
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Version: %s\n", result.Version)
fmt.Printf("Has errors: %v\n", len(result.Errors) > 0)
}
Output: Version: 3.0.3 Has errors: false
Example (DeepCopy) ¶
Example_deepCopy demonstrates using DeepCopy to create independent copies of parsed documents. This is useful when you need to modify a document without affecting the original (e.g., in fixers or converters).
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
// Type assert to get the OAS3 document
original, ok := result.Document.(*parser.OAS3Document)
if !ok {
log.Fatal("expected OAS3 document")
}
// Create a deep copy of the document
docCopy := original.DeepCopy()
// Modify the copy without affecting the original
docCopy.Info.Title = "Modified Petstore API"
fmt.Printf("Original title: %s\n", original.Info.Title)
fmt.Printf("Copy title: %s\n", docCopy.Info.Title)
}
Output: Original title: Petstore API Copy title: Modified Petstore API
Example (DocumentAccessor) ¶
Example_documentAccessor demonstrates using the DocumentAccessor interface for version-agnostic access to OpenAPI documents. This allows writing code that works identically for both OAS 2.0 and OAS 3.x without type switches.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
// Get version-agnostic accessor
accessor := result.AsAccessor()
if accessor == nil {
log.Fatal("unsupported document type")
}
// Works identically for both OAS 2.0 and OAS 3.x
fmt.Printf("API: %s\n", accessor.GetInfo().Title)
fmt.Printf("Paths: %d\n", len(accessor.GetPaths()))
fmt.Printf("Schemas: %d\n", len(accessor.GetSchemas()))
fmt.Printf("Schema ref prefix: %s\n", accessor.SchemaRefPrefix())
}
Output: API: Petstore API Paths: 2 Schemas: 4 Schema ref prefix: #/components/schemas/
Example (DocumentTypeHelpers) ¶
Example_documentTypeHelpers demonstrates using the type assertion helper methods to safely extract version-specific documents and check document versions.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
// Parse an OAS 3.x document
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
// Use IsOAS2/IsOAS3 for version checking without type assertions
fmt.Printf("Is OAS 2.0: %v\n", result.IsOAS2())
fmt.Printf("Is OAS 3.x: %v\n", result.IsOAS3())
// Use OAS3Document for safe type assertion
if doc, ok := result.OAS3Document(); ok {
fmt.Printf("API Title: %s\n", doc.Info.Title)
}
}
Output: Is OAS 2.0: false Is OAS 3.x: true API Title: Petstore API
Example (FunctionalOptions) ¶
Example_functionalOptions demonstrates parsing using functional options.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
parser.WithValidateStructure(true),
parser.WithResolveRefs(false),
)
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Version: %s\n", result.Version)
fmt.Printf("Format: %s\n", result.SourceFormat)
}
Output: Version: 3.0.3 Format: yaml
Example (ParseFromURL) ¶
Example_parseFromURL demonstrates parsing a specification directly from a URL.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result, err := parser.ParseWithOptions(
parser.WithFilePath("https://petstore.swagger.io/v2/swagger.json"),
parser.WithValidateStructure(true),
)
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Version: %s\n", result.Version)
fmt.Printf("Format: %s\n", result.SourceFormat)
}
Output:
Example (ParseWithHTTPRefs) ¶
Example_parseWithHTTPRefs demonstrates parsing with HTTP/HTTPS $ref resolution. This is useful for specifications that reference external schemas via URLs. HTTP resolution is opt-in for security (prevents SSRF attacks).
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
// Enable HTTP reference resolution (opt-in for security)
result, err := parser.ParseWithOptions(
parser.WithFilePath("spec-with-http-refs.yaml"),
parser.WithResolveRefs(true),
parser.WithResolveHTTPRefs(true), // Enable HTTP $ref resolution
// parser.WithInsecureSkipVerify(true), // For self-signed certs (dev only)
)
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Version: %s\n", result.Version)
fmt.Printf("Errors: %d\n", len(result.Errors))
// HTTP responses are cached, size-limited, and protected against circular refs
}
Output:
Example (ParseWithRefs) ¶
Example_parseWithRefs demonstrates parsing with external reference resolution enabled.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
p := parser.New()
p.ResolveRefs = true
result, err := p.Parse("../testdata/with-external-refs.yaml")
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Version: %s\n", result.Version)
fmt.Printf("Has warnings: %v\n", len(result.Warnings) > 0)
}
Output: Version: 3.0.3 Has warnings: false
Example (PreserveOrder) ¶
Example_preserveOrder demonstrates order-preserving marshaling. When WithPreserveOrder is enabled, the output maintains the original field order from the source document.
package main
import (
"fmt"
"github.com/erraggy/oastools/parser"
)
func main() {
// A simple spec with fields in a specific order
spec := `{"openapi":"3.1.0","info":{"title":"Test","version":"1.0"},"paths":{}}`
result, err := parser.ParseWithOptions(
parser.WithBytes([]byte(spec)),
parser.WithPreserveOrder(true),
)
if err != nil {
fmt.Println("Error:", err)
return
}
// Check if order was preserved
fmt.Printf("Order preserved: %v\n", result.HasPreservedOrder())
// Marshal back to JSON - order is maintained
output, err := result.MarshalOrderedJSON()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(output))
}
Output: Order preserved: true {"openapi":"3.1.0","info":{"title":"Test","version":"1.0"},"paths":{}}
Example (ReusableParser) ¶
Example_reusableParser demonstrates creating a reusable parser instance for processing multiple files with the same configuration.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
// Configure parser once
p := parser.New()
p.ResolveRefs = true
p.ValidateStructure = true
p.ResolveHTTPRefs = false // Keep HTTP refs disabled for security
// Parse multiple files with same config
files := []string{
"../testdata/petstore-3.0.yaml",
"../testdata/petstore-2.0.yaml",
}
for _, file := range files {
result, err := p.Parse(file)
if err != nil {
log.Printf("Error parsing %s: %v", file, err)
continue
}
fmt.Printf("%s: version=%s, errors=%d\n",
file, result.Version, len(result.Errors))
}
}
Output:
Example (WithSourceName) ¶
Example_withSourceName demonstrates setting a meaningful source name when parsing from bytes or io.Reader. This is important when later joining documents, as the source name appears in collision reports and warnings.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
// When parsing from bytes (e.g., fetched from HTTP), the default source name
// is "ParseBytes.yaml" which isn't helpful for collision reports.
specData := []byte(`openapi: "3.0.0"
info:
title: Users API
version: "1.0"
paths:
/users:
get:
summary: List users
responses:
'200':
description: OK
`)
// Use WithSourceName to set a meaningful identifier
result, err := parser.ParseWithOptions(
parser.WithBytes(specData),
parser.WithSourceName("users-api"),
)
if err != nil {
log.Fatal(err)
}
// The source name is now "users-api" instead of "ParseBytes.yaml"
fmt.Printf("Source: %s\n", result.SourcePath)
fmt.Printf("Version: %s\n", result.Version)
}
Output: Source: users-api Version: 3.0.0
Index ¶
- Constants
- func FormatBytes(size int64) string
- func GetOperations(pathItem *PathItem, version OASVersion) map[string]*Operation
- type Callback
- type Components
- type Contact
- type ContextLogger
- func (c *ContextLogger) Context() context.Context
- func (c *ContextLogger) Debug(msg string, attrs ...any)
- func (c *ContextLogger) Error(msg string, attrs ...any)
- func (c *ContextLogger) Info(msg string, attrs ...any)
- func (c *ContextLogger) Warn(msg string, attrs ...any)
- func (c *ContextLogger) With(attrs ...any) Logger
- type Discriminator
- func (in *Discriminator) DeepCopy() *Discriminator
- func (in *Discriminator) DeepCopyInto(out *Discriminator)
- func (d *Discriminator) MarshalJSON() ([]byte, error)
- func (d *Discriminator) MarshalYAML() (any, error)
- func (d *Discriminator) UnmarshalJSON(data []byte) error
- func (d *Discriminator) UnmarshalYAML(node *yaml.Node) error
- type DocumentAccessor
- type DocumentStats
- type Encoding
- type Example
- type ExternalDocs
- type HTTPFetcher
- type Header
- type Info
- type Items
- type License
- type Link
- type Logger
- type MediaType
- type NopLogger
- type OAS2Document
- func (in *OAS2Document) DeepCopy() *OAS2Document
- func (in *OAS2Document) DeepCopyInto(out *OAS2Document)
- func (d *OAS2Document) Equals(other *OAS2Document) bool
- func (d *OAS2Document) GetExternalDocs() *ExternalDocs
- func (d *OAS2Document) GetInfo() *Info
- func (d *OAS2Document) GetParameters() map[string]*Parameter
- func (d *OAS2Document) GetPaths() Paths
- func (d *OAS2Document) GetResponses() map[string]*Response
- func (d *OAS2Document) GetSchemas() map[string]*Schema
- func (d *OAS2Document) GetSecurity() []SecurityRequirement
- func (d *OAS2Document) GetSecuritySchemes() map[string]*SecurityScheme
- func (d *OAS2Document) GetTags() []*Tag
- func (d *OAS2Document) GetVersion() OASVersion
- func (d *OAS2Document) GetVersionString() string
- func (d *OAS2Document) MarshalJSON() ([]byte, error)
- func (d *OAS2Document) SchemaRefPrefix() string
- func (d *OAS2Document) UnmarshalJSON(data []byte) error
- type OAS3Document
- func (in *OAS3Document) DeepCopy() *OAS3Document
- func (in *OAS3Document) DeepCopyInto(out *OAS3Document)
- func (d *OAS3Document) Equals(other *OAS3Document) bool
- func (d *OAS3Document) GetExternalDocs() *ExternalDocs
- func (d *OAS3Document) GetInfo() *Info
- func (d *OAS3Document) GetParameters() map[string]*Parameter
- func (d *OAS3Document) GetPaths() Paths
- func (d *OAS3Document) GetResponses() map[string]*Response
- func (d *OAS3Document) GetSchemas() map[string]*Schema
- func (d *OAS3Document) GetSecurity() []SecurityRequirement
- func (d *OAS3Document) GetSecuritySchemes() map[string]*SecurityScheme
- func (d *OAS3Document) GetTags() []*Tag
- func (d *OAS3Document) GetVersion() OASVersion
- func (d *OAS3Document) GetVersionString() string
- func (d *OAS3Document) MarshalJSON() ([]byte, error)
- func (d *OAS3Document) SchemaRefPrefix() string
- func (d *OAS3Document) UnmarshalJSON(data []byte) error
- type OASVersion
- type OAuthFlow
- type OAuthFlows
- type Operation
- type Option
- func WithBytes(data []byte) Option
- func WithFilePath(path string) Option
- func WithHTTPClient(client *http.Client) Option
- func WithInsecureSkipVerify(enabled bool) Option
- func WithLogger(l Logger) Option
- func WithMaxCachedDocuments(count int) Option
- func WithMaxFileSize(size int) Option
- func WithMaxInputSize(size int) Option
- func WithMaxRefDepth(depth int) Option
- func WithPreserveOrder(enabled bool) Option
- func WithReader(r io.Reader) Option
- func WithResolveHTTPRefs(enabled bool) Option
- func WithResolveRefs(enabled bool) Option
- func WithSourceMap(enabled bool) Option
- func WithSourceName(name string) Option
- func WithUserAgent(ua string) Option
- func WithValidateStructure(enabled bool) Option
- type Parameter
- type ParseResult
- func (pr *ParseResult) AsAccessor() DocumentAccessor
- func (pr *ParseResult) Copy() *ParseResult
- func (pr *ParseResult) DocumentEquals(other *ParseResult) bool
- func (pr *ParseResult) Equals(other *ParseResult) bool
- func (pr *ParseResult) HasPreservedOrder() bool
- func (pr *ParseResult) IsOAS2() bool
- func (pr *ParseResult) IsOAS3() bool
- func (pr *ParseResult) MarshalOrderedJSON() ([]byte, error)
- func (pr *ParseResult) MarshalOrderedJSONIndent(prefix, indent string) ([]byte, error)
- func (pr *ParseResult) MarshalOrderedYAML() ([]byte, error)
- func (pr *ParseResult) OAS2Document() (*OAS2Document, bool)
- func (pr *ParseResult) OAS3Document() (*OAS3Document, bool)
- type Parser
- type PathItem
- type Paths
- type RefLocation
- type RefResolver
- func (r *RefResolver) HasCircularRefs() bool
- func (r *RefResolver) Resolve(doc map[string]any, ref string) (any, error)
- func (r *RefResolver) ResolveAllRefs(doc map[string]any) error
- func (r *RefResolver) ResolveExternal(ref string) (any, error)
- func (r *RefResolver) ResolveHTTP(ref string) (any, error)
- func (r *RefResolver) ResolveLocal(doc map[string]any, ref string) (any, error)
- func (r *RefResolver) SetCacheTTL(ttl time.Duration)
- type Reference
- type RequestBody
- type Response
- type Responses
- type Schema
- type SecurityRequirement
- type SecurityScheme
- type Server
- type ServerVariable
- type SlogAdapter
- type SourceFormat
- type SourceLocation
- type SourceMap
- func (sm *SourceMap) Copy() *SourceMap
- func (sm *SourceMap) Get(path string) SourceLocation
- func (sm *SourceMap) GetKey(path string) SourceLocation
- func (sm *SourceMap) GetRef(path string) RefLocation
- func (sm *SourceMap) Has(path string) bool
- func (sm *SourceMap) Len() int
- func (sm *SourceMap) Merge(other *SourceMap)
- func (sm *SourceMap) Paths() []string
- type Tag
- type XML
Examples ¶
- Package
- Package (DeepCopy)
- Package (DocumentAccessor)
- Package (DocumentTypeHelpers)
- Package (FunctionalOptions)
- Package (ParseFromURL)
- Package (ParseWithHTTPRefs)
- Package (ParseWithRefs)
- Package (PreserveOrder)
- Package (ReusableParser)
- Package (WithSourceName)
- Discriminator (StringForm)
- OAS2Document.Equals
- OAS3Document.Equals
- ParseResult.DocumentEquals
- ParseResult.Equals
- Schema (Items)
- Schema.Equals
- WithHTTPClient
- WithHTTPClient (Proxy)
Constants ¶
const ( // ParamInQuery indicates the parameter is passed in the query string ParamInQuery = "query" // ParamInQueryString indicates the parameter is the entire query string, // described as a single value (OAS 3.2+). // // Distinct from ParamInQuery, and mutually exclusive with it: a querystring // parameter describes the whole query string, so it cannot coexist with a // parameter describing one member of it. See the OAS 3.2 Parameter Object. ParamInQueryString = "querystring" // ParamInHeader indicates the parameter is passed in a request header ParamInHeader = "header" // ParamInPath indicates the parameter is part of the URL path ParamInPath = "path" // ParamInCookie indicates the parameter is passed as a cookie (OAS 3.0+) ParamInCookie = "cookie" // ParamInFormData indicates the parameter is passed as form data (OAS 2.0 only) ParamInFormData = "formData" // ParamInBody indicates the parameter is in the request body (OAS 2.0 only) ParamInBody = "body" )
Parameter location constants (used in Parameter.In field)
const ( // MaxRefDepth is the maximum depth allowed for nested $ref resolution // This prevents stack overflow from deeply nested (but non-circular) references MaxRefDepth = 100 // MaxCachedDocuments is the maximum number of external documents to cache // This prevents memory exhaustion from documents with many external references MaxCachedDocuments = 100 // MaxFileSize is the maximum size (in bytes) allowed for external reference files // This prevents resource exhaustion from loading arbitrarily large files // Set to 10MB which should be sufficient for most OpenAPI documents MaxFileSize = 10 * 1024 * 1024 // 10MB )
Variables ¶
This section is empty.
Functions ¶
func FormatBytes ¶ added in v1.9.2
FormatBytes formats a byte count into a human-readable string using binary units (KiB, MiB, etc.)
func GetOperations ¶ added in v1.15.2
func GetOperations(pathItem *PathItem, version OASVersion) map[string]*Operation
GetOperations extracts a map of all operations from a PathItem based on the OAS version. Returns a map with keys for HTTP methods and values pointing to the corresponding Operation (or nil if not defined). The returned map includes methods supported by the specified OAS version:
- OAS 2.0: get, put, post, delete, options, head, patch
- OAS 3.0-3.1: get, put, post, delete, options, head, patch, trace
- OAS 3.2+: get, put, post, delete, options, head, patch, trace, query, plus any additionalOperations
Types ¶
type Components ¶
type Components struct {
Schemas map[string]*Schema `yaml:"schemas,omitempty" json:"schemas,omitempty"`
Responses map[string]*Response `yaml:"responses,omitempty" json:"responses,omitempty"`
Parameters map[string]*Parameter `yaml:"parameters,omitempty" json:"parameters,omitempty"`
Examples map[string]*Example `yaml:"examples,omitempty" json:"examples,omitempty"`
RequestBodies map[string]*RequestBody `yaml:"requestBodies,omitempty" json:"requestBodies,omitempty"`
Headers map[string]*Header `yaml:"headers,omitempty" json:"headers,omitempty"`
SecuritySchemes map[string]*SecurityScheme `yaml:"securitySchemes,omitempty" json:"securitySchemes,omitempty"`
Links map[string]*Link `yaml:"links,omitempty" json:"links,omitempty"`
Callbacks map[string]*Callback `yaml:"callbacks,omitempty" json:"callbacks,omitempty"`
// OAS 3.1+ additions
PathItems map[string]*PathItem `yaml:"pathItems,omitempty" json:"pathItems,omitempty"` // OAS 3.1+
// OAS 3.2+ additions
MediaTypes map[string]*MediaType `yaml:"mediaTypes,omitempty" json:"mediaTypes,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Components holds reusable objects for different aspects of the OAS (OAS 3.0+)
func (*Components) DeepCopy ¶ added in v1.20.0
func (in *Components) DeepCopy() *Components
DeepCopy creates a deep copy of Components.
func (*Components) DeepCopyInto ¶ added in v1.20.0
func (in *Components) DeepCopyInto(out *Components)
DeepCopyInto copies Components into out.
func (*Components) MarshalJSON ¶ added in v1.6.1
func (c *Components) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for Components. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Components) UnmarshalJSON ¶ added in v1.6.1
func (c *Components) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for Components. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Contact ¶
type Contact struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
URL string `yaml:"url,omitempty" json:"url,omitempty"`
Email string `yaml:"email,omitempty" json:"email,omitempty"`
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Contact information for the exposed API
func (*Contact) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Contact into out.
func (*Contact) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Contact. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Contact) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Contact. This captures unknown fields (specification extensions like x-*) in the Extra map.
type ContextLogger ¶ added in v1.21.0
type ContextLogger struct {
// contains filtered or unexported fields
}
ContextLogger wraps a Logger to include context in all operations. This is useful for passing request-scoped values through the logging pipeline.
func NewContextLogger ¶ added in v1.21.0
func NewContextLogger(logger Logger, ctx context.Context) *ContextLogger
NewContextLogger creates a new ContextLogger.
func (*ContextLogger) Context ¶ added in v1.21.0
func (c *ContextLogger) Context() context.Context
Context returns the context associated with this logger.
func (*ContextLogger) Debug ¶ added in v1.21.0
func (c *ContextLogger) Debug(msg string, attrs ...any)
Debug implements Logger.
func (*ContextLogger) Error ¶ added in v1.21.0
func (c *ContextLogger) Error(msg string, attrs ...any)
Error implements Logger.
func (*ContextLogger) Info ¶ added in v1.21.0
func (c *ContextLogger) Info(msg string, attrs ...any)
Info implements Logger.
func (*ContextLogger) Warn ¶ added in v1.21.0
func (c *ContextLogger) Warn(msg string, attrs ...any)
Warn implements Logger.
func (*ContextLogger) With ¶ added in v1.21.0
func (c *ContextLogger) With(attrs ...any) Logger
With implements Logger.
type Discriminator ¶
type Discriminator struct {
PropertyName string `yaml:"propertyName" json:"propertyName"`
Mapping map[string]string `yaml:"mapping,omitempty" json:"mapping,omitempty"` // OAS 3.0+ only
// DefaultMapping names the schema to use when the discriminating property is
// absent, or holds a value no Mapping key covers (OAS 3.2+).
// https://spec.openapis.org/oas/v3.2.0.html#discriminator-default-mapping
//
// Reference-bearing exactly as a Mapping value is: a schema name or a URI
// reference. Every pass that rewrites Mapping (joining, renaming, converting)
// must rewrite this too, or leave a dangling reference while reporting success.
//
// Its conditional requirement is a validator rule, not a parser one: whether the
// discriminating property is optional is only knowable from the enclosing
// schema.
DefaultMapping string `yaml:"defaultMapping,omitempty" json:"defaultMapping,omitempty"` // OAS 3.2+
Extra map[string]any `yaml:",inline" json:"-"`
// StringForm reports that this discriminator came from — and should be
// written back as — the OAS 2.0 bare-string form (`discriminator: petType`)
// rather than the OAS 3.0+ object form. It is not itself a specification
// field, so it is excluded from both JSON and YAML.
//
// Mapping and Extra have no representation in the string form and are
// dropped when serializing with StringForm set. Converting between
// dialects must set or clear this flag; see the converter package.
StringForm bool `yaml:"-" json:"-"`
}
Discriminator represents a discriminator for polymorphism.
The two OAS dialects spell this differently. In OAS 2.0 the Schema Object's discriminator is a bare string naming the property; in OAS 3.0+ it is an object with propertyName and an optional mapping. A single Go type serves both: the string form decodes into PropertyName with StringForm set, so the dialect a document was written in survives a parse/serialize round trip.
Example (StringForm) ¶
ExampleDiscriminator_stringForm demonstrates how the two discriminator dialects are decoded and written back. OAS 2.0 spells a discriminator as a bare string naming the property, while OAS 3.0+ uses an object with propertyName. Both decode into a Discriminator; StringForm records which spelling the document used so it round-trips unchanged.
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
// OAS 2.0 uses the bare-string form: `discriminator: petType`
spec := []byte(`swagger: "2.0"
info:
title: Pet Store
version: "1.0"
paths: {}
definitions:
Pet:
type: object
discriminator: petType
required:
- petType
properties:
petType:
type: string
`)
result, err := parser.ParseWithOptions(parser.WithBytes(spec))
if err != nil {
log.Fatal(err)
}
doc, ok := result.OAS2Document()
if !ok {
log.Fatal("expected OAS2 document")
}
discriminator := doc.Definitions["Pet"].Discriminator
fmt.Printf("PropertyName: %s\n", discriminator.PropertyName)
fmt.Printf("StringForm: %v\n", discriminator.StringForm)
// Marshaling reproduces the form the document used
stringForm, err := json.Marshal(discriminator)
if err != nil {
log.Fatal(err)
}
fmt.Printf("OAS 2.0 output: %s\n", stringForm)
// Targeting OAS 3.0+ means clearing the flag, which selects the object form.
// The converter package does this for you in both directions.
discriminator.StringForm = false
objectForm, err := json.Marshal(discriminator)
if err != nil {
log.Fatal(err)
}
fmt.Printf("OAS 3.x output: %s\n", objectForm)
}
Output: PropertyName: petType StringForm: true OAS 2.0 output: "petType" OAS 3.x output: {"propertyName":"petType"}
func (*Discriminator) DeepCopy ¶ added in v1.20.0
func (in *Discriminator) DeepCopy() *Discriminator
DeepCopy creates a deep copy of Discriminator.
func (*Discriminator) DeepCopyInto ¶ added in v1.20.0
func (in *Discriminator) DeepCopyInto(out *Discriminator)
DeepCopyInto copies Discriminator into out.
func (*Discriminator) MarshalJSON ¶ added in v1.6.1
func (d *Discriminator) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for Discriminator. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
When StringForm is set the OAS 2.0 bare-string form is emitted instead, so a 2.0 document is not silently rewritten into the OAS 3.x object form.
func (*Discriminator) MarshalYAML ¶ added in v1.57.0
func (d *Discriminator) MarshalYAML() (any, error)
MarshalYAML implements custom YAML marshaling for Discriminator.
When StringForm is set the OAS 2.0 bare-string form is emitted, so a 2.0 document is not silently rewritten into the OAS 3.x object form. Mapping and Extra have no representation in that form and are dropped.
func (*Discriminator) UnmarshalJSON ¶ added in v1.6.1
func (d *Discriminator) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for Discriminator. This captures unknown fields (specification extensions like x-*) in the Extra map.
Both dialects are accepted: the OAS 2.0 bare-string form decodes into PropertyName with StringForm set, and the OAS 3.0+ object form decodes normally. Rejecting the form that is wrong for the document's version is the validator's job, since the parser cannot see the version from here.
func (*Discriminator) UnmarshalYAML ¶ added in v1.57.0
func (d *Discriminator) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML implements custom YAML unmarshaling for Discriminator.
Both dialects are accepted: the OAS 2.0 string-only form (`discriminator: petType`) decodes into PropertyName with StringForm set to true, and the OAS 3.0+ mapping form decodes normally. Rejecting the form that is wrong for the document's version is the validator's job, since the parser cannot see the version from here.
type DocumentAccessor ¶ added in v1.33.1
type DocumentAccessor interface {
// GetInfo returns the API metadata.
// Returns nil if Info is not set.
GetInfo() *Info
// GetPaths returns the path items map.
// Returns nil if Paths is not set.
GetPaths() Paths
// GetTags returns the tag definitions.
// Returns nil if Tags is not set.
GetTags() []*Tag
// GetSecurity returns the global security requirements.
// Returns nil if Security is not set.
GetSecurity() []SecurityRequirement
// GetExternalDocs returns the external documentation reference.
// Returns nil if ExternalDocs is not set.
GetExternalDocs() *ExternalDocs
// GetSchemas returns the schema definitions.
// For OAS 2.0: returns doc.Definitions
// For OAS 3.x: returns doc.Components.Schemas
// Returns nil if the schema container is not set (OAS2 Definitions nil, or
// OAS3 Components nil or Components.Schemas nil). An empty map is returned
// only when the container exists but has no entries.
GetSchemas() map[string]*Schema
// GetSecuritySchemes returns the security scheme definitions.
// For OAS 2.0: returns doc.SecurityDefinitions
// For OAS 3.x: returns doc.Components.SecuritySchemes
// Returns nil if no security schemes are defined.
GetSecuritySchemes() map[string]*SecurityScheme
// GetParameters returns the reusable parameter definitions.
// For OAS 2.0: returns doc.Parameters
// For OAS 3.x: returns doc.Components.Parameters
// Returns nil if no parameters are defined.
GetParameters() map[string]*Parameter
// GetResponses returns the reusable response definitions.
// For OAS 2.0: returns doc.Responses
// For OAS 3.x: returns doc.Components.Responses
// Returns nil if no responses are defined.
GetResponses() map[string]*Response
// GetVersion returns the OASVersion enum for this document.
GetVersion() OASVersion
// GetVersionString returns the version string (e.g., "2.0", "3.0.3", "3.1.0").
GetVersionString() string
// SchemaRefPrefix returns the JSON reference prefix for schemas.
// For OAS 2.0: returns "#/definitions/"
// For OAS 3.x: returns "#/components/schemas/"
SchemaRefPrefix() string
}
DocumentAccessor provides a unified read-only interface for accessing common fields across OAS 2.0 and OAS 3.x documents. This interface abstracts away version-specific differences for fields that have semantic equivalence between versions.
Fields with identical structure across versions ¶
- Info, Paths, Tags, Security, ExternalDocs
Fields with semantic equivalence (different locations, same meaning) ¶
- Schemas: OAS 2.0 doc.Definitions vs OAS 3.x doc.Components.Schemas
- SecuritySchemes: OAS 2.0 doc.SecurityDefinitions vs OAS 3.x doc.Components.SecuritySchemes
- Parameters: OAS 2.0 doc.Parameters vs OAS 3.x doc.Components.Parameters
- Responses: OAS 2.0 doc.Responses vs OAS 3.x doc.Components.Responses
Accessing version-specific fields ¶
For version-specific fields (Servers, Webhooks, RequestBodies, etc.), use the version-specific document types directly via ParseResult.OAS2Document or ParseResult.OAS3Document methods on the ParseResult.
Return value semantics ¶
Methods returning maps (GetPaths, GetSchemas, etc.) return nil when the field is not set or when a required parent object is nil (e.g., OAS3 Components). These methods return direct references to the underlying data structures, so callers should avoid modifying the returned values unless they intend to mutate the document. If you need to modify the data, make a copy first.
Example usage ¶
result, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
if accessor := result.AsAccessor(); accessor != nil {
// Works for both OAS 2.0 and OAS 3.x
for path, item := range accessor.GetPaths() {
fmt.Println("Path:", path)
}
for name, schema := range accessor.GetSchemas() {
fmt.Println("Schema:", name)
}
}
type DocumentStats ¶ added in v1.11.0
type DocumentStats struct {
PathCount int // Number of paths defined
OperationCount int // Total number of operations across all paths
SchemaCount int // Number of schemas/definitions
}
DocumentStats contains statistical information about an OAS document
func GetDocumentStats ¶ added in v1.11.0
func GetDocumentStats(doc any) DocumentStats
GetDocumentStats returns statistics for a parsed OAS document
type Encoding ¶
type Encoding struct {
ContentType string `yaml:"contentType,omitempty" json:"contentType,omitempty"`
Headers map[string]*Header `yaml:"headers,omitempty" json:"headers,omitempty"`
Style string `yaml:"style,omitempty" json:"style,omitempty"`
Explode *bool `yaml:"explode,omitempty" json:"explode,omitempty"`
AllowReserved bool `yaml:"allowReserved,omitempty" json:"allowReserved,omitempty"`
// Encoding describes the encoding of nested properties (OAS 3.2+).
Encoding map[string]*Encoding `yaml:"encoding,omitempty" json:"encoding,omitempty"` // OAS 3.2+
// ItemEncoding describes the encoding of each item of a sequence (OAS 3.2+).
ItemEncoding *Encoding `yaml:"itemEncoding,omitempty" json:"itemEncoding,omitempty"` // OAS 3.2+
// PrefixEncoding describes the encoding of the leading items of a sequence
// positionally (OAS 3.2+).
PrefixEncoding []*Encoding `yaml:"prefixEncoding,omitempty" json:"prefixEncoding,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Encoding defines encoding for a specific property (OAS 3.0+) https://spec.openapis.org/oas/v3.2.0.html#encoding-object
OAS 3.2 makes this type recursive: an encoding may describe its own nested properties or sequence items. Anything walking an Encoding must recurse through Encoding, ItemEncoding, and PrefixEncoding.
func (*Encoding) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Encoding into out.
func (*Encoding) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Encoding. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Encoding) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Encoding. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Example ¶
type Example struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Value any `yaml:"value,omitempty" json:"value,omitempty"`
ExternalValue string `yaml:"externalValue,omitempty" json:"externalValue,omitempty"`
// DataValue holds the example as structured data, superseding Value (OAS 3.2+).
// https://spec.openapis.org/oas/v3.2.0.html#example-data-value
//
// Its exclusivity with Value is enforced by the validator, not here: a parser
// that rejected the pair could not round trip the document to report it.
DataValue any `yaml:"dataValue,omitempty" json:"dataValue,omitempty"` // OAS 3.2+
// SerializedValue holds the example already serialized for its media type,
// excluding Value and ExternalValue (OAS 3.2+).
// https://spec.openapis.org/oas/v3.2.0.html#example-serialized-value
SerializedValue string `yaml:"serializedValue,omitempty" json:"serializedValue,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Example represents an example object (OAS 3.0+)
func (*Example) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Example into out.
func (*Example) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Example. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Example) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Example. This captures unknown fields (specification extensions like x-*) in the Extra map.
type ExternalDocs ¶
type ExternalDocs struct {
Description string `yaml:"description,omitempty" json:"description,omitempty"`
URL string `yaml:"url" json:"url"`
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
ExternalDocs allows referencing external documentation
func (*ExternalDocs) DeepCopy ¶ added in v1.20.0
func (in *ExternalDocs) DeepCopy() *ExternalDocs
DeepCopy creates a deep copy of ExternalDocs.
func (*ExternalDocs) DeepCopyInto ¶ added in v1.20.0
func (in *ExternalDocs) DeepCopyInto(out *ExternalDocs)
DeepCopyInto copies ExternalDocs into out.
func (*ExternalDocs) MarshalJSON ¶ added in v1.6.1
func (e *ExternalDocs) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for ExternalDocs. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*ExternalDocs) UnmarshalJSON ¶ added in v1.6.1
func (e *ExternalDocs) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for ExternalDocs. This captures unknown fields (specification extensions like x-*) in the Extra map.
type HTTPFetcher ¶ added in v1.18.0
HTTPFetcher is a function type for fetching content from HTTP/HTTPS URLs Returns the response body, content-type header, and any error
type Header ¶
type Header struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Required bool `yaml:"required,omitempty" json:"required,omitempty"`
Deprecated bool `yaml:"deprecated,omitempty" json:"deprecated,omitempty"` // OAS 3.0+
// OAS 3.0+ fields
Style string `yaml:"style,omitempty" json:"style,omitempty"`
Explode *bool `yaml:"explode,omitempty" json:"explode,omitempty"`
Schema *Schema `yaml:"schema,omitempty" json:"schema,omitempty"`
Example any `yaml:"example,omitempty" json:"example,omitempty"`
Examples map[string]*Example `yaml:"examples,omitempty" json:"examples,omitempty"`
Content map[string]*MediaType `yaml:"content,omitempty" json:"content,omitempty"`
// OAS 2.0 fields
Type string `yaml:"type,omitempty" json:"type,omitempty"` // OAS 2.0
Format string `yaml:"format,omitempty" json:"format,omitempty"` // OAS 2.0
Items *Items `yaml:"items,omitempty" json:"items,omitempty"` // OAS 2.0
CollectionFormat string `yaml:"collectionFormat,omitempty" json:"collectionFormat,omitempty"` // OAS 2.0
Default any `yaml:"default,omitempty" json:"default,omitempty"` // OAS 2.0
Maximum *float64 `yaml:"maximum,omitempty" json:"maximum,omitempty"` // OAS 2.0
ExclusiveMaximum bool `yaml:"exclusiveMaximum,omitempty" json:"exclusiveMaximum,omitempty"` // OAS 2.0
Minimum *float64 `yaml:"minimum,omitempty" json:"minimum,omitempty"` // OAS 2.0
ExclusiveMinimum bool `yaml:"exclusiveMinimum,omitempty" json:"exclusiveMinimum,omitempty"` // OAS 2.0
MaxLength *int `yaml:"maxLength,omitempty" json:"maxLength,omitempty"` // OAS 2.0
MinLength *int `yaml:"minLength,omitempty" json:"minLength,omitempty"` // OAS 2.0
Pattern string `yaml:"pattern,omitempty" json:"pattern,omitempty"` // OAS 2.0
MaxItems *int `yaml:"maxItems,omitempty" json:"maxItems,omitempty"` // OAS 2.0
MinItems *int `yaml:"minItems,omitempty" json:"minItems,omitempty"` // OAS 2.0
UniqueItems bool `yaml:"uniqueItems,omitempty" json:"uniqueItems,omitempty"` // OAS 2.0
Enum []any `yaml:"enum,omitempty" json:"enum,omitempty"` // OAS 2.0
MultipleOf *float64 `yaml:"multipleOf,omitempty" json:"multipleOf,omitempty"` // OAS 2.0
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Header represents a header object
func (*Header) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Header into out.
func (*Header) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Header. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Header) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Header. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Info ¶
type Info struct {
Title string `yaml:"title" json:"title"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
TermsOfService string `yaml:"termsOfService,omitempty" json:"termsOfService,omitempty"`
Contact *Contact `yaml:"contact,omitempty" json:"contact,omitempty"`
License *License `yaml:"license,omitempty" json:"license,omitempty"`
Version string `yaml:"version" json:"version"`
// OAS 3.1+ additions
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"`
// Extra captures specification extensions (fields starting with "x-")
// and any other fields not explicitly defined in the struct
Extra map[string]any `yaml:",inline" json:"-"`
}
Info provides metadata about the API Common across all OAS versions (2.0, 3.0, 3.1, 3.2)
func (*Info) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Info into out.
func (*Info) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Info. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Info) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Info. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Items ¶
type Items struct {
Type string `yaml:"type" json:"type"`
Format string `yaml:"format,omitempty" json:"format,omitempty"`
Items *Items `yaml:"items,omitempty" json:"items,omitempty"`
CollectionFormat string `yaml:"collectionFormat,omitempty" json:"collectionFormat,omitempty"`
Default any `yaml:"default,omitempty" json:"default,omitempty"`
Maximum *float64 `yaml:"maximum,omitempty" json:"maximum,omitempty"`
ExclusiveMaximum bool `yaml:"exclusiveMaximum,omitempty" json:"exclusiveMaximum,omitempty"`
Minimum *float64 `yaml:"minimum,omitempty" json:"minimum,omitempty"`
ExclusiveMinimum bool `yaml:"exclusiveMinimum,omitempty" json:"exclusiveMinimum,omitempty"`
MaxLength *int `yaml:"maxLength,omitempty" json:"maxLength,omitempty"`
MinLength *int `yaml:"minLength,omitempty" json:"minLength,omitempty"`
Pattern string `yaml:"pattern,omitempty" json:"pattern,omitempty"`
MaxItems *int `yaml:"maxItems,omitempty" json:"maxItems,omitempty"`
MinItems *int `yaml:"minItems,omitempty" json:"minItems,omitempty"`
UniqueItems bool `yaml:"uniqueItems,omitempty" json:"uniqueItems,omitempty"`
Enum []any `yaml:"enum,omitempty" json:"enum,omitempty"`
MultipleOf *float64 `yaml:"multipleOf,omitempty" json:"multipleOf,omitempty"`
Extra map[string]any `yaml:",inline" json:"-"`
}
Items represents items object for array parameters (OAS 2.0)
func (*Items) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Items into out.
func (*Items) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Items. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Items) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Items. This captures unknown fields (specification extensions like x-*) in the Extra map.
type License ¶
type License struct {
Name string `yaml:"name" json:"name"`
URL string `yaml:"url,omitempty" json:"url,omitempty"`
Identifier string `yaml:"identifier,omitempty" json:"identifier,omitempty"` // OAS 3.1+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
License information for the exposed API
func (*License) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies License into out.
func (*License) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for License. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*License) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for License. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Link ¶
type Link struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
OperationRef string `yaml:"operationRef,omitempty" json:"operationRef,omitempty"`
OperationID string `yaml:"operationId,omitempty" json:"operationId,omitempty"`
Parameters map[string]any `yaml:"parameters,omitempty" json:"parameters,omitempty"`
RequestBody any `yaml:"requestBody,omitempty" json:"requestBody,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Server *Server `yaml:"server,omitempty" json:"server,omitempty"`
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Link represents a possible design-time link for a response (OAS 3.0+)
func (*Link) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Link into out.
func (*Link) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Link. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Link) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Link. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Logger ¶ added in v1.21.0
type Logger interface {
// Debug logs at debug level. Use for detailed diagnostic information.
Debug(msg string, attrs ...any)
// Info logs at info level. Use for general operational information.
Info(msg string, attrs ...any)
// Warn logs at warn level. Use for potentially harmful situations.
Warn(msg string, attrs ...any)
// Error logs at error level. Use for error conditions.
Error(msg string, attrs ...any)
// With returns a new Logger with the given attributes prepended to every log.
// This is useful for adding context that applies to multiple log calls.
With(attrs ...any) Logger
}
Logger is the interface that oastools uses for structured logging.
The interface is designed to be minimal yet compatible with popular logging libraries including log/slog, zap, and zerolog. It uses variadic key-value pairs for structured attributes, following the same convention as log/slog.
Implementations should treat attrs as alternating key-value pairs:
logger.Debug("resolved reference", "ref", "#/components/schemas/Pet", "depth", 3)
Keys should be strings, and values can be any type that the underlying logger can serialize.
Usage with log/slog ¶
Use NewSlogAdapter to wrap a standard library slog.Logger:
handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})
slogger := slog.New(handler)
logger := parser.NewSlogAdapter(slogger)
result, err := parser.ParseWithOptions(
parser.WithFilePath("api.yaml"),
parser.WithLogger(logger),
)
Usage with zap ¶
Create a simple adapter implementing the Logger interface:
type ZapAdapter struct {
logger *zap.SugaredLogger
}
func (z *ZapAdapter) Debug(msg string, attrs ...any) { z.logger.Debugw(msg, attrs...) }
func (z *ZapAdapter) Info(msg string, attrs ...any) { z.logger.Infow(msg, attrs...) }
func (z *ZapAdapter) Warn(msg string, attrs ...any) { z.logger.Warnw(msg, attrs...) }
func (z *ZapAdapter) Error(msg string, attrs ...any) { z.logger.Errorw(msg, attrs...) }
func (z *ZapAdapter) With(attrs ...any) parser.Logger {
return &ZapAdapter{logger: z.logger.With(attrs...)}
}
Usage with zerolog ¶
Create a simple adapter implementing the Logger interface:
type ZerologAdapter struct {
logger zerolog.Logger
}
func (z *ZerologAdapter) Debug(msg string, attrs ...any) {
e := z.logger.Debug()
for i := 0; i < len(attrs)-1; i += 2 {
e = e.Interface(fmt.Sprint(attrs[i]), attrs[i+1])
}
e.Msg(msg)
}
// ... implement other methods similarly
type MediaType ¶
type MediaType struct {
Schema *Schema `yaml:"schema,omitempty" json:"schema,omitempty"`
Example any `yaml:"example,omitempty" json:"example,omitempty"`
Examples map[string]*Example `yaml:"examples,omitempty" json:"examples,omitempty"`
Encoding map[string]*Encoding `yaml:"encoding,omitempty" json:"encoding,omitempty"`
// ItemSchema describes each item of a sequential media type (OAS 3.2+).
ItemSchema *Schema `yaml:"itemSchema,omitempty" json:"itemSchema,omitempty"` // OAS 3.2+
// ItemEncoding describes how each item of a sequential media type is encoded
// (OAS 3.2+).
ItemEncoding *Encoding `yaml:"itemEncoding,omitempty" json:"itemEncoding,omitempty"` // OAS 3.2+
// PrefixEncoding describes the encoding of the leading items of a sequential
// media type positionally, the way prefixItems does for a schema (OAS 3.2+).
PrefixEncoding []*Encoding `yaml:"prefixEncoding,omitempty" json:"prefixEncoding,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
MediaType provides schema and examples for the media type (OAS 3.0+)
The three OAS 3.2 fields describe sequential media types (a stream of items such as JSON Lines or multipart), where the schema and encoding apply to each item rather than to the payload as a whole. https://spec.openapis.org/oas/v3.2.0.html#media-type-object
func (*MediaType) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies MediaType into out.
func (*MediaType) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for MediaType. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*MediaType) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for MediaType. This captures unknown fields (specification extensions like x-*) in the Extra map.
type NopLogger ¶ added in v1.21.0
type NopLogger struct{}
NopLogger is a no-op logger that discards all output. It is the default logger used when no logger is configured.
type OAS2Document ¶
type OAS2Document struct {
Swagger string `yaml:"swagger" json:"swagger"` // Required: "2.0"
Info *Info `yaml:"info" json:"info"` // Required
Host string `yaml:"host,omitempty" json:"host,omitempty"`
BasePath string `yaml:"basePath,omitempty" json:"basePath,omitempty"`
Schemes []string `yaml:"schemes,omitempty" json:"schemes,omitempty"` // e.g., ["http", "https"]
Consumes []string `yaml:"consumes,omitempty" json:"consumes,omitempty"`
Produces []string `yaml:"produces,omitempty" json:"produces,omitempty"`
Paths Paths `yaml:"paths" json:"paths"` // Required
Definitions map[string]*Schema `yaml:"definitions,omitempty" json:"definitions,omitempty"`
Parameters map[string]*Parameter `yaml:"parameters,omitempty" json:"parameters,omitempty"`
Responses map[string]*Response `yaml:"responses,omitempty" json:"responses,omitempty"`
SecurityDefinitions map[string]*SecurityScheme `yaml:"securityDefinitions,omitempty" json:"securityDefinitions,omitempty"`
Security []SecurityRequirement `yaml:"security,omitempty" json:"security,omitempty"`
Tags []*Tag `yaml:"tags,omitempty" json:"tags,omitempty"`
ExternalDocs *ExternalDocs `yaml:"externalDocs,omitempty" json:"externalDocs,omitempty"`
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
OASVersion OASVersion `yaml:"-" json:"-"`
}
OAS2Document represents an OpenAPI Specification 2.0 (Swagger) document Reference: https://spec.openapis.org/oas/v2.0.html
func (*OAS2Document) DeepCopy ¶ added in v1.20.0
func (in *OAS2Document) DeepCopy() *OAS2Document
DeepCopy creates a deep copy of OAS2Document.
func (*OAS2Document) DeepCopyInto ¶ added in v1.20.0
func (in *OAS2Document) DeepCopyInto(out *OAS2Document)
DeepCopyInto copies OAS2Document into out.
func (*OAS2Document) Equals ¶ added in v1.44.0
func (d *OAS2Document) Equals(other *OAS2Document) bool
Equals compares two OAS2Documents for structural equality. Returns true if both documents have identical content.
Example ¶
ExampleOAS2Document_Equals demonstrates comparing two OAS 2.0 (Swagger) documents for equality.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-2.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
doc, ok := result.OAS2Document()
if !ok {
log.Fatal("expected OAS2 document")
}
// DeepCopy creates an identical document
docCopy := doc.DeepCopy()
fmt.Printf("Copy equals original: %v\n", doc.Equals(docCopy))
// Modify the copy
docCopy.Info.Title = "Modified Swagger API"
fmt.Printf("After modification: %v\n", doc.Equals(docCopy))
}
Output: Copy equals original: true After modification: false
func (*OAS2Document) GetExternalDocs ¶ added in v1.33.1
func (d *OAS2Document) GetExternalDocs() *ExternalDocs
GetExternalDocs returns the external documentation for OAS 2.0 documents.
func (*OAS2Document) GetInfo ¶ added in v1.33.1
func (d *OAS2Document) GetInfo() *Info
GetInfo returns the API metadata for OAS 2.0 documents.
func (*OAS2Document) GetParameters ¶ added in v1.33.1
func (d *OAS2Document) GetParameters() map[string]*Parameter
GetParameters returns the reusable parameter definitions for OAS 2.0 documents.
func (*OAS2Document) GetPaths ¶ added in v1.33.1
func (d *OAS2Document) GetPaths() Paths
GetPaths returns the path items for OAS 2.0 documents.
func (*OAS2Document) GetResponses ¶ added in v1.33.1
func (d *OAS2Document) GetResponses() map[string]*Response
GetResponses returns the reusable response definitions for OAS 2.0 documents.
func (*OAS2Document) GetSchemas ¶ added in v1.33.1
func (d *OAS2Document) GetSchemas() map[string]*Schema
GetSchemas returns the schema definitions for OAS 2.0 documents. In OAS 2.0, schemas are stored in doc.Definitions.
func (*OAS2Document) GetSecurity ¶ added in v1.33.1
func (d *OAS2Document) GetSecurity() []SecurityRequirement
GetSecurity returns the global security requirements for OAS 2.0 documents.
func (*OAS2Document) GetSecuritySchemes ¶ added in v1.33.1
func (d *OAS2Document) GetSecuritySchemes() map[string]*SecurityScheme
GetSecuritySchemes returns the security scheme definitions for OAS 2.0 documents. In OAS 2.0, these are stored in doc.SecurityDefinitions.
func (*OAS2Document) GetTags ¶ added in v1.33.1
func (d *OAS2Document) GetTags() []*Tag
GetTags returns the tag definitions for OAS 2.0 documents.
func (*OAS2Document) GetVersion ¶ added in v1.33.1
func (d *OAS2Document) GetVersion() OASVersion
GetVersion returns the OASVersion for OAS 2.0 documents.
func (*OAS2Document) GetVersionString ¶ added in v1.33.1
func (d *OAS2Document) GetVersionString() string
GetVersionString returns the version string for OAS 2.0 documents.
func (*OAS2Document) MarshalJSON ¶ added in v1.6.1
func (d *OAS2Document) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for OAS2Document. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline". The Extra map is merged after marshaling the base struct to ensure specification extensions appear at the root level.
func (*OAS2Document) SchemaRefPrefix ¶ added in v1.33.1
func (d *OAS2Document) SchemaRefPrefix() string
SchemaRefPrefix returns the JSON reference prefix for OAS 2.0 schemas.
func (*OAS2Document) UnmarshalJSON ¶ added in v1.6.1
func (d *OAS2Document) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for OAS2Document. This captures unknown fields (specification extensions like x-*) in the Extra map.
type OAS3Document ¶
type OAS3Document struct {
OpenAPI string `yaml:"openapi" json:"openapi"` // Required: "3.0.x", "3.1.x", or "3.2.x"
Info *Info `yaml:"info" json:"info"` // Required
Servers []*Server `yaml:"servers,omitempty" json:"servers,omitempty"`
Paths Paths `yaml:"paths,omitempty" json:"paths,omitempty"` // Required in 3.0, optional in 3.1+
Webhooks map[string]*PathItem `yaml:"webhooks,omitempty" json:"webhooks,omitempty"` // OAS 3.1+
Components *Components `yaml:"components,omitempty" json:"components,omitempty"`
Security []SecurityRequirement `yaml:"security,omitempty" json:"security,omitempty"`
Tags []*Tag `yaml:"tags,omitempty" json:"tags,omitempty"`
ExternalDocs *ExternalDocs `yaml:"externalDocs,omitempty" json:"externalDocs,omitempty"`
OASVersion OASVersion `yaml:"-" json:"-"`
// OAS 3.1+ additions
JSONSchemaDialect string `yaml:"jsonSchemaDialect,omitempty" json:"jsonSchemaDialect,omitempty"` // OAS 3.1+
// OAS 3.2+ additions
Self string `yaml:"$self,omitempty" json:"$self,omitempty"` // OAS 3.2+ - Document identity/base URI
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
OAS3Document represents an OpenAPI Specification 3.x document Supports OAS 3.0.x, 3.1.x, and 3.2.x References: - OAS 3.0.0: https://spec.openapis.org/oas/v3.0.0.html - OAS 3.1.0: https://spec.openapis.org/oas/v3.1.0.html - OAS 3.2.0: https://spec.openapis.org/oas/v3.2.0.html
func (*OAS3Document) DeepCopy ¶ added in v1.20.0
func (in *OAS3Document) DeepCopy() *OAS3Document
DeepCopy creates a deep copy of OAS3Document.
func (*OAS3Document) DeepCopyInto ¶ added in v1.20.0
func (in *OAS3Document) DeepCopyInto(out *OAS3Document)
DeepCopyInto copies OAS3Document into out.
func (*OAS3Document) Equals ¶ added in v1.44.0
func (d *OAS3Document) Equals(other *OAS3Document) bool
Equals compares two OAS3Documents for structural equality. Returns true if both documents have identical content.
Example ¶
ExampleOAS3Document_Equals demonstrates comparing two OAS 3.x documents for equality.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
doc, ok := result.OAS3Document()
if !ok {
log.Fatal("expected OAS3 document")
}
// DeepCopy creates an identical document
docCopy := doc.DeepCopy()
fmt.Printf("Copy equals original: %v\n", doc.Equals(docCopy))
// Modify the copy
docCopy.Info.Title = "Modified API"
fmt.Printf("After modification: %v\n", doc.Equals(docCopy))
}
Output: Copy equals original: true After modification: false
func (*OAS3Document) GetExternalDocs ¶ added in v1.33.1
func (d *OAS3Document) GetExternalDocs() *ExternalDocs
GetExternalDocs returns the external documentation for OAS 3.x documents.
func (*OAS3Document) GetInfo ¶ added in v1.33.1
func (d *OAS3Document) GetInfo() *Info
GetInfo returns the API metadata for OAS 3.x documents.
func (*OAS3Document) GetParameters ¶ added in v1.33.1
func (d *OAS3Document) GetParameters() map[string]*Parameter
GetParameters returns the reusable parameter definitions for OAS 3.x documents. In OAS 3.x, these are stored in doc.Components.Parameters.
func (*OAS3Document) GetPaths ¶ added in v1.33.1
func (d *OAS3Document) GetPaths() Paths
GetPaths returns the path items for OAS 3.x documents.
func (*OAS3Document) GetResponses ¶ added in v1.33.1
func (d *OAS3Document) GetResponses() map[string]*Response
GetResponses returns the reusable response definitions for OAS 3.x documents. In OAS 3.x, these are stored in doc.Components.Responses.
func (*OAS3Document) GetSchemas ¶ added in v1.33.1
func (d *OAS3Document) GetSchemas() map[string]*Schema
GetSchemas returns the schema definitions for OAS 3.x documents. In OAS 3.x, schemas are stored in doc.Components.Schemas.
func (*OAS3Document) GetSecurity ¶ added in v1.33.1
func (d *OAS3Document) GetSecurity() []SecurityRequirement
GetSecurity returns the global security requirements for OAS 3.x documents.
func (*OAS3Document) GetSecuritySchemes ¶ added in v1.33.1
func (d *OAS3Document) GetSecuritySchemes() map[string]*SecurityScheme
GetSecuritySchemes returns the security scheme definitions for OAS 3.x documents. In OAS 3.x, these are stored in doc.Components.SecuritySchemes.
func (*OAS3Document) GetTags ¶ added in v1.33.1
func (d *OAS3Document) GetTags() []*Tag
GetTags returns the tag definitions for OAS 3.x documents.
func (*OAS3Document) GetVersion ¶ added in v1.33.1
func (d *OAS3Document) GetVersion() OASVersion
GetVersion returns the OASVersion for OAS 3.x documents.
func (*OAS3Document) GetVersionString ¶ added in v1.33.1
func (d *OAS3Document) GetVersionString() string
GetVersionString returns the version string for OAS 3.x documents.
func (*OAS3Document) MarshalJSON ¶ added in v1.6.1
func (d *OAS3Document) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for OAS3Document. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*OAS3Document) SchemaRefPrefix ¶ added in v1.33.1
func (d *OAS3Document) SchemaRefPrefix() string
SchemaRefPrefix returns the JSON reference prefix for OAS 3.x schemas.
func (*OAS3Document) UnmarshalJSON ¶ added in v1.6.1
func (d *OAS3Document) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for OAS3Document. This captures unknown fields (specification extensions like x-*) in the Extra map.
type OASVersion ¶
type OASVersion int
OASVersion represents each canonical version of the OpenAPI Specification that may be found at: https://github.com/OAI/OpenAPI-Specification/releases
const ( // Unknown represents an unknown or invalid OAS version Unknown OASVersion = iota // OASVersion20 OpenAPI Specification Version 2.0 (Swagger) OASVersion20 // OASVersion300 OpenAPI Specification Version 3.0.0 OASVersion300 // OASVersion301 OpenAPI Specification Version 3.0.1 OASVersion301 // OASVersion302 OpenAPI Specification Version 3.0.2 OASVersion302 // OASVersion303 OpenAPI Specification Version 3.0.3 OASVersion303 // OASVersion304 OpenAPI Specification Version 3.0.4 OASVersion304 // OASVersion310 OpenAPI Specification Version 3.1.0 OASVersion310 // OASVersion311 OpenAPI Specification Version 3.1.1 OASVersion311 // OASVersion312 OpenAPI Specification Version 3.1.2 OASVersion312 // OASVersion320 OpenAPI Specification Version 3.2.0 OASVersion320 )
func ParseVersion ¶
func ParseVersion(s string) (OASVersion, bool)
ParseVersion will attempt to parse the string s into an OASVersion, and returns false if not valid. This function supports: 1. Exact version matches (e.g., "2.0", "3.0.3") 2. Future patch versions in known major.minor series (e.g., "3.0.5" maps to "3.0.4") 3. Pre-release versions (e.g., "3.0.0-rc0") map to closest match without exceeding base version
For example: - "3.0.5" (not yet released) maps to OASVersion304 (3.0.4) - latest in 3.0.x series - "3.0.0-rc0" maps to OASVersion300 (3.0.0) - the base version - "3.0.5-rc1" maps to OASVersion304 (3.0.4) - closest without exceeding 3.0.5
func (OASVersion) IsValid ¶
func (v OASVersion) IsValid() bool
IsValid returns true if this is a valid version
func (OASVersion) String ¶
func (v OASVersion) String() string
type OAuthFlow ¶
type OAuthFlow struct {
AuthorizationURL string `yaml:"authorizationUrl,omitempty" json:"authorizationUrl,omitempty"`
TokenURL string `yaml:"tokenUrl,omitempty" json:"tokenUrl,omitempty"`
RefreshURL string `yaml:"refreshUrl,omitempty" json:"refreshUrl,omitempty"`
Scopes map[string]string `yaml:"scopes" json:"scopes"`
// DeviceAuthorizationURL is the device authorization endpoint, required by the
// deviceAuthorization flow (OAS 3.2+).
DeviceAuthorizationURL string `yaml:"deviceAuthorizationUrl,omitempty" json:"deviceAuthorizationUrl,omitempty"` // OAS 3.2+
Extra map[string]any `yaml:",inline" json:"-"`
}
OAuthFlow represents configuration for a single OAuth flow (OAS 3.0+)
func (*OAuthFlow) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies OAuthFlow into out.
func (*OAuthFlow) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for OAuthFlow. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*OAuthFlow) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for OAuthFlow. This captures unknown fields (specification extensions like x-*) in the Extra map.
type OAuthFlows ¶
type OAuthFlows struct {
Implicit *OAuthFlow `yaml:"implicit,omitempty" json:"implicit,omitempty"`
Password *OAuthFlow `yaml:"password,omitempty" json:"password,omitempty"`
ClientCredentials *OAuthFlow `yaml:"clientCredentials,omitempty" json:"clientCredentials,omitempty"`
AuthorizationCode *OAuthFlow `yaml:"authorizationCode,omitempty" json:"authorizationCode,omitempty"`
// DeviceAuthorization configures the OAuth 2.0 Device Authorization Grant
// (RFC 8628) flow (OAS 3.2+).
DeviceAuthorization *OAuthFlow `yaml:"deviceAuthorization,omitempty" json:"deviceAuthorization,omitempty"` // OAS 3.2+
Extra map[string]any `yaml:",inline" json:"-"`
}
OAuthFlows allows configuration of the supported OAuth Flows (OAS 3.0+)
func (*OAuthFlows) DeepCopy ¶ added in v1.20.0
func (in *OAuthFlows) DeepCopy() *OAuthFlows
DeepCopy creates a deep copy of OAuthFlows.
func (*OAuthFlows) DeepCopyInto ¶ added in v1.20.0
func (in *OAuthFlows) DeepCopyInto(out *OAuthFlows)
DeepCopyInto copies OAuthFlows into out.
func (*OAuthFlows) MarshalJSON ¶ added in v1.6.1
func (of *OAuthFlows) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for OAuthFlows. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*OAuthFlows) UnmarshalJSON ¶ added in v1.6.1
func (of *OAuthFlows) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for OAuthFlows. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Operation ¶
type Operation struct {
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
ExternalDocs *ExternalDocs `yaml:"externalDocs,omitempty" json:"externalDocs,omitempty"`
OperationID string `yaml:"operationId,omitempty" json:"operationId,omitempty"`
Parameters []*Parameter `yaml:"parameters,omitempty" json:"parameters,omitempty"`
RequestBody *RequestBody `yaml:"requestBody,omitempty" json:"requestBody,omitempty"` // OAS 3.0+
Responses *Responses `yaml:"responses" json:"responses"`
Callbacks map[string]*Callback `yaml:"callbacks,omitempty" json:"callbacks,omitempty"` // OAS 3.0+
Deprecated bool `yaml:"deprecated,omitempty" json:"deprecated,omitempty"`
Security []SecurityRequirement `yaml:"security,omitempty" json:"security,omitempty"`
Servers []*Server `yaml:"servers,omitempty" json:"servers,omitempty"` // OAS 3.0+
// OAS 2.0 specific
Consumes []string `yaml:"consumes,omitempty" json:"consumes,omitempty"` // OAS 2.0
Produces []string `yaml:"produces,omitempty" json:"produces,omitempty"` // OAS 2.0
Schemes []string `yaml:"schemes,omitempty" json:"schemes,omitempty"` // OAS 2.0
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Operation describes a single API operation on a path
func (*Operation) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Operation into out.
func (*Operation) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Operation. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Operation) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Operation. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Option ¶ added in v1.11.0
type Option func(*parseConfig) error
Option is a function that configures a parse operation
func WithFilePath ¶ added in v1.11.0
WithFilePath specifies a file path or URL as the input source
func WithHTTPClient ¶ added in v1.45.2
WithHTTPClient sets a custom HTTP client for fetching URLs. When set, the client is used as-is for all HTTP requests. The InsecureSkipVerify option is ignored when a custom client is provided (configure TLS settings on your client's transport instead).
If the client is nil, this option has no effect (default client is used).
Example with custom timeout:
client := &http.Client{Timeout: 60 * time.Second}
result, err := parser.ParseWithOptions(
parser.WithFilePath("https://example.com/api.yaml"),
parser.WithHTTPClient(client),
)
Example with proxy:
proxyURL, _ := url.Parse("http://proxy.example.com:8080")
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
}
result, err := parser.ParseWithOptions(
parser.WithFilePath("https://internal.corp/api.yaml"),
parser.WithHTTPClient(client),
)
Example ¶
ExampleWithHTTPClient demonstrates using a custom HTTP client with a longer timeout.
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/erraggy/oastools/parser"
)
func main() {
// Create a custom HTTP client with longer timeout for slow networks
client := &http.Client{
Timeout: 60 * time.Second,
}
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
parser.WithHTTPClient(client),
)
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Version: %s\n", result.Version)
}
Output: Version: 3.0.3
Example (Proxy) ¶
ExampleWithHTTPClient_proxy demonstrates configuring a proxy for corporate environments.
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/erraggy/oastools/parser"
)
func main() {
// This example shows the configuration pattern for corporate proxies.
// In a real scenario, you would use an actual proxy URL.
// For this example, we use a direct client
client := &http.Client{Timeout: 30 * time.Second}
result, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
parser.WithHTTPClient(client),
)
if err != nil {
log.Fatalf("failed to parse: %v", err)
}
fmt.Printf("Parsed: %s\n", result.Version)
}
Output: Parsed: 3.0.3
func WithInsecureSkipVerify ¶ added in v1.18.0
WithInsecureSkipVerify disables TLS certificate verification for HTTPS refs Use with caution - only enable for testing or internal servers with self-signed certs Note: This option only takes effect when ResolveHTTPRefs is also enabled
func WithLogger ¶ added in v1.21.0
WithLogger sets a structured logger for debug output during parsing. By default, no logging is performed (nil logger).
The logger interface is compatible with log/slog, zap, and zerolog. Use NewSlogAdapter to wrap a *slog.Logger.
Example:
logger := parser.NewSlogAdapter(slog.Default())
result, err := parser.ParseWithOptions(
parser.WithFilePath("api.yaml"),
parser.WithLogger(logger),
)
func WithMaxCachedDocuments ¶ added in v1.21.0
WithMaxCachedDocuments sets the maximum number of external documents to cache during reference resolution. This prevents memory exhaustion from documents with many external references. A value of 0 means use the default (100). Returns an error if count is negative.
func WithMaxFileSize ¶ added in v1.21.0
WithMaxFileSize sets the maximum file size in bytes for external reference files. This prevents resource exhaustion from loading arbitrarily large files. A value of 0 means use the default (10MB). Returns an error if size is negative.
func WithMaxInputSize ¶ added in v1.52.0
WithMaxInputSize sets the maximum input size in bytes for the primary document. This prevents resource exhaustion from reading oversized inputs via ParseReader or ParseBytes. A value of 0 means use the default (100 MiB). Returns an error if size is negative.
func WithMaxRefDepth ¶ added in v1.21.0
WithMaxRefDepth sets the maximum depth for resolving nested $ref pointers. This prevents stack overflow from deeply nested (but non-circular) references. A value of 0 means use the default (100). Returns an error if depth is negative.
func WithPreserveOrder ¶ added in v1.45.0
WithPreserveOrder enables order-preserving marshaling. When enabled, ParseResult stores the original yaml.Node structure, allowing MarshalOrderedJSON/MarshalOrderedYAML to emit fields in the same order as the source document.
This is useful for:
- Hash-based caching where roundtrip identity matters
- Minimizing diffs when editing and re-serializing specs
- Maintaining human-friendly key ordering
Default: false
Example:
result, err := parser.ParseWithOptions(
parser.WithFilePath("api.yaml"),
parser.WithPreserveOrder(true),
)
orderedJSON, _ := result.MarshalOrderedJSON()
func WithReader ¶ added in v1.11.0
WithReader specifies an io.Reader as the input source
func WithResolveHTTPRefs ¶ added in v1.18.0
WithResolveHTTPRefs enables resolution of HTTP/HTTPS $ref URLs This is disabled by default for security (SSRF protection) Must be explicitly enabled when parsing specifications with HTTP refs Note: This option only takes effect when ResolveRefs is also enabled
func WithResolveRefs ¶ added in v1.11.0
WithResolveRefs enables or disables reference resolution ($ref) Default: false
func WithSourceMap ¶ added in v1.27.0
WithSourceMap enables or disables source location tracking. When enabled, the ParseResult.SourceMap will contain line/column information for each JSON path in the document. Default: false
func WithSourceName ¶ added in v1.40.0
WithSourceName specifies a meaningful name for the source document. This is particularly useful when parsing from bytes or reader, where the default names ("ParseBytes.yaml", "ParseReader.yaml") are not descriptive. The name is used in error messages, collision reports when joining, and other diagnostic output.
Example:
result, err := parser.ParseWithOptions(
parser.WithBytes(data),
parser.WithSourceName("users-api"),
)
This helps when joining multiple pre-parsed documents:
// Without WithSourceName, collision reports show "ParseBytes.yaml vs ParseBytes.yaml" // With WithSourceName, collision reports show "users-api vs billing-api"
func WithUserAgent ¶ added in v1.11.0
WithUserAgent sets the User-Agent string for HTTP requests Default: "oastools/vX.Y.Z"
func WithValidateStructure ¶ added in v1.11.0
WithValidateStructure enables or disables basic structure validation Default: true
type Parameter ¶
type Parameter struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Name string `yaml:"name,omitempty" json:"name,omitempty"`
In string `yaml:"in,omitempty" json:"in,omitempty"` // "query", "header", "path", "cookie" (OAS 3.0+), "formData", "body" (OAS 2.0)
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Required bool `yaml:"required,omitempty" json:"required,omitempty"`
Deprecated bool `yaml:"deprecated,omitempty" json:"deprecated,omitempty"` // OAS 3.0+
// OAS 3.0+ fields
Style string `yaml:"style,omitempty" json:"style,omitempty"`
Explode *bool `yaml:"explode,omitempty" json:"explode,omitempty"`
AllowReserved bool `yaml:"allowReserved,omitempty" json:"allowReserved,omitempty"`
Schema *Schema `yaml:"schema,omitempty" json:"schema,omitempty"`
Example any `yaml:"example,omitempty" json:"example,omitempty"`
Examples map[string]*Example `yaml:"examples,omitempty" json:"examples,omitempty"`
Content map[string]*MediaType `yaml:"content,omitempty" json:"content,omitempty"`
// OAS 2.0 fields
Type string `yaml:"type,omitempty" json:"type,omitempty"` // OAS 2.0
Format string `yaml:"format,omitempty" json:"format,omitempty"` // OAS 2.0
AllowEmptyValue bool `yaml:"allowEmptyValue,omitempty" json:"allowEmptyValue,omitempty"` // OAS 2.0
Items *Items `yaml:"items,omitempty" json:"items,omitempty"` // OAS 2.0
CollectionFormat string `yaml:"collectionFormat,omitempty" json:"collectionFormat,omitempty"` // OAS 2.0
Default any `yaml:"default,omitempty" json:"default,omitempty"` // OAS 2.0
Maximum *float64 `yaml:"maximum,omitempty" json:"maximum,omitempty"` // OAS 2.0
ExclusiveMaximum bool `yaml:"exclusiveMaximum,omitempty" json:"exclusiveMaximum,omitempty"` // OAS 2.0
Minimum *float64 `yaml:"minimum,omitempty" json:"minimum,omitempty"` // OAS 2.0
ExclusiveMinimum bool `yaml:"exclusiveMinimum,omitempty" json:"exclusiveMinimum,omitempty"` // OAS 2.0
MaxLength *int `yaml:"maxLength,omitempty" json:"maxLength,omitempty"` // OAS 2.0
MinLength *int `yaml:"minLength,omitempty" json:"minLength,omitempty"` // OAS 2.0
Pattern string `yaml:"pattern,omitempty" json:"pattern,omitempty"` // OAS 2.0
MaxItems *int `yaml:"maxItems,omitempty" json:"maxItems,omitempty"` // OAS 2.0
MinItems *int `yaml:"minItems,omitempty" json:"minItems,omitempty"` // OAS 2.0
UniqueItems bool `yaml:"uniqueItems,omitempty" json:"uniqueItems,omitempty"` // OAS 2.0
Enum []any `yaml:"enum,omitempty" json:"enum,omitempty"` // OAS 2.0
MultipleOf *float64 `yaml:"multipleOf,omitempty" json:"multipleOf,omitempty"` // OAS 2.0
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Parameter describes a single operation parameter.
Name and In are required by the specification but are still tagged omitempty: a $ref parameter arrives from the parser with every sibling field empty, and emitting name: "" and in: "" alongside the $ref corrupts the object on every round trip. An inline parameter that genuinely lacks them is invalid either way, and the validator reports it — the serializer is not the right place to surface that defect.
func (*Parameter) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Parameter into out.
func (*Parameter) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Parameter. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Parameter) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Parameter. This captures unknown fields (specification extensions like x-*) in the Extra map.
type ParseResult ¶
type ParseResult struct {
// SourcePath is the document's input source path that it was read from.
// Note: if the source was not a file path, this will be set to the name of the method
// and end in '.yaml' or '.json' based on the detected format
SourcePath string
// SourceFormat is the format of the source file (JSON or YAML)
SourceFormat SourceFormat
// Version is the detected OAS version string (e.g., "2.0", "3.0.3", "3.1.0")
Version string
// Data contains the raw parsed data as a map, potentially with resolved $refs
Data map[string]any
// Document contains the version-specific parsed document:
// - *OAS2Document for OpenAPI 2.0
// - *OAS3Document for OpenAPI 3.x
Document any
// Errors contains any parsing or validation errors encountered
Errors []error
// Warnings contains non-fatal issues such as ref resolution failures
Warnings []string
// OASVersion is the enumerated version of the OpenAPI specification
OASVersion OASVersion
// LoadTime is the time taken to load the source data (file, URL, etc.)
LoadTime time.Duration
// SourceSize is the size of the source data in bytes
SourceSize int64
// Stats contains statistical information about the document
Stats DocumentStats
// SourceMap contains JSON path to source location mappings.
// Only populated when Parser.BuildSourceMap is true.
SourceMap *SourceMap
// contains filtered or unexported fields
}
ParseResult contains the parsed OpenAPI specification and metadata. This structure provides both the raw parsed data and version-specific typed representations of the OpenAPI document.
Immutability ¶
While Go does not enforce immutability, callers should treat ParseResult as read-only after parsing. Modifying the returned document may lead to unexpected behavior if the document is cached or shared across multiple operations.
For document modification use cases:
- Version conversion: Use the converter package
- Document merging: Use the joiner package
- Manual modification: Create a deep copy first using Copy() method
Example of safe modification:
original, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
modified := original.Copy() // Deep copy
// Now safe to modify 'modified' without affecting 'original'
func ParseWithOptions ¶ added in v1.11.0
func ParseWithOptions(opts ...Option) (*ParseResult, error)
ParseWithOptions parses an OpenAPI specification using functional options. This provides a flexible, extensible API that combines input source selection and configuration in a single function call.
Example:
result, err := parser.ParseWithOptions(
parser.WithFilePath("openapi.yaml"),
parser.WithResolveRefs(true),
)
func (*ParseResult) AsAccessor ¶ added in v1.33.1
func (pr *ParseResult) AsAccessor() DocumentAccessor
AsAccessor returns a DocumentAccessor for version-agnostic access to the parsed document. Returns nil if the document type is unknown or nil.
This method provides a convenient way to work with parsed documents without needing to check the version and perform type assertions:
result, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
if accessor := result.AsAccessor(); accessor != nil {
schemas := accessor.GetSchemas() // Works for both OAS 2.0 and 3.x
}
func (*ParseResult) Copy ¶ added in v1.11.1
func (pr *ParseResult) Copy() *ParseResult
Copy creates a deep copy of the ParseResult, including all nested documents and data. This is useful when you need to modify a parsed document without affecting the original.
The deep copy is performed using JSON marshaling and unmarshaling to ensure all nested structures and maps are properly copied.
Example:
original, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
modified := original.Copy()
// Modify the copy without affecting the original
if doc, ok := modified.Document.(*parser.OAS3Document); ok {
doc.Info.Title = "Modified API"
}
func (*ParseResult) DocumentEquals ¶ added in v1.44.0
func (pr *ParseResult) DocumentEquals(other *ParseResult) bool
DocumentEquals compares only the Document field, ignoring version. This is useful when comparing documents that may have been converted between versions but should have equivalent content.
Example ¶
ExampleParseResult_DocumentEquals demonstrates comparing documents ignoring version metadata. This is useful when comparing specifications that may have been converted between versions.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
result1, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
// Create a copy with the same document
result2, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
// DocumentEquals compares only the document content
fmt.Printf("Documents equal: %v\n", result1.DocumentEquals(result2))
}
Output: Documents equal: true
func (*ParseResult) Equals ¶ added in v1.44.0
func (pr *ParseResult) Equals(other *ParseResult) bool
Equals compares two ParseResults for semantic equality. It returns true if both results represent the same OpenAPI specification, ignoring runtime metadata like LoadTime and SourcePath.
Equality is determined by:
- Version and OASVersion match
- Document contents are structurally equal
Fields explicitly NOT compared (runtime metadata):
- SourcePath, SourceFormat (how it was loaded)
- LoadTime, SourceSize (runtime metrics)
- Errors, Warnings (parse diagnostics)
- Data (raw map; Document is the canonical representation)
- SourceMap (debugging aid)
- Stats (derived from Document)
Example ¶
ExampleParseResult_Equals demonstrates comparing two ParseResults for semantic equality. This is useful for testing, caching, or detecting specification changes.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
// Parse the same specification twice
result1, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
result2, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-3.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
// Compare for semantic equality (ignores metadata like LoadTime, SourcePath)
fmt.Printf("Same content: %v\n", result1.Equals(result2))
// Parse a different specification
result3, err := parser.ParseWithOptions(
parser.WithFilePath("../testdata/petstore-2.0.yaml"),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Different specs: %v\n", result1.Equals(result3))
}
Output: Same content: true Different specs: false
func (*ParseResult) HasPreservedOrder ¶ added in v1.45.0
func (pr *ParseResult) HasPreservedOrder() bool
HasPreservedOrder returns true if this ParseResult has preserved the original field ordering from the source document. This is true when PreserveOrder was enabled during parsing.
func (*ParseResult) IsOAS2 ¶ added in v1.25.0
func (pr *ParseResult) IsOAS2() bool
IsOAS2 returns true if the parsed document is an OpenAPI 2.0 (Swagger) specification. This is a convenience method for checking the document version without type assertions.
func (*ParseResult) IsOAS3 ¶ added in v1.25.0
func (pr *ParseResult) IsOAS3() bool
IsOAS3 returns true if the parsed document is an OpenAPI 3.x specification (including 3.0.x, 3.1.x, and 3.2.x). This is a convenience method for checking the document version without type assertions.
func (*ParseResult) MarshalOrderedJSON ¶ added in v1.45.0
func (pr *ParseResult) MarshalOrderedJSON() ([]byte, error)
MarshalOrderedJSON marshals the parsed document to JSON with fields in the same order as the original source document.
This method requires PreserveOrder to be enabled during parsing. If PreserveOrder was not enabled, it falls back to standard JSON marshaling which sorts map keys alphabetically.
The ordered output is useful for:
- Hash-based caching where roundtrip identity matters
- Minimizing diffs when editing and re-serializing specs
- Maintaining human-friendly key ordering
Example:
p := parser.New()
p.PreserveOrder = true
result, _ := p.Parse("api.yaml")
orderedJSON, _ := result.MarshalOrderedJSON()
func (*ParseResult) MarshalOrderedJSONIndent ¶ added in v1.45.0
func (pr *ParseResult) MarshalOrderedJSONIndent(prefix, indent string) ([]byte, error)
MarshalOrderedJSONIndent marshals the parsed document to indented JSON with fields in the same order as the original source document.
This method requires PreserveOrder to be enabled during parsing. If PreserveOrder was not enabled, it falls back to standard JSON marshaling.
func (*ParseResult) MarshalOrderedYAML ¶ added in v1.45.0
func (pr *ParseResult) MarshalOrderedYAML() ([]byte, error)
MarshalOrderedYAML marshals the parsed document to YAML with fields in the same order as the original source document.
This method requires PreserveOrder to be enabled during parsing. If PreserveOrder was not enabled, it falls back to standard YAML marshaling which sorts map keys alphabetically.
Example:
p := parser.New()
p.PreserveOrder = true
result, _ := p.Parse("api.yaml")
orderedYAML, _ := result.MarshalOrderedYAML()
func (*ParseResult) OAS2Document ¶ added in v1.25.0
func (pr *ParseResult) OAS2Document() (*OAS2Document, bool)
OAS2Document returns the parsed document as an OAS2Document if the specification is version 2.0 (Swagger), and a boolean indicating whether the type assertion succeeded. This is a convenience method that provides a safe type assertion pattern.
Example:
result, _ := parser.ParseWithOptions(parser.WithFilePath("swagger.yaml"))
if doc, ok := result.OAS2Document(); ok {
fmt.Println("API Title:", doc.Info.Title)
}
func (*ParseResult) OAS3Document ¶ added in v1.25.0
func (pr *ParseResult) OAS3Document() (*OAS3Document, bool)
OAS3Document returns the parsed document as an OAS3Document if the specification is version 3.x, and a boolean indicating whether the type assertion succeeded. This is a convenience method that provides a safe type assertion pattern.
Example:
result, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
if doc, ok := result.OAS3Document(); ok {
fmt.Println("API Title:", doc.Info.Title)
}
type Parser ¶
type Parser struct {
// ResolveRefs determines whether to resolve $ref references
ResolveRefs bool
// ResolveHTTPRefs determines whether to resolve HTTP/HTTPS $ref URLs
// This is disabled by default for security (SSRF protection)
// Must be explicitly enabled when parsing specifications with HTTP refs
ResolveHTTPRefs bool
// InsecureSkipVerify disables TLS certificate verification for HTTP refs
// Use with caution - only enable for testing or internal servers with self-signed certs
InsecureSkipVerify bool
// ValidateStructure determines whether to perform basic structure validation
ValidateStructure bool
// UserAgent is the User-Agent string used when fetching URLs
// Defaults to "oastools" if not set
UserAgent string
// HTTPClient is the HTTP client used for fetching URLs.
// If nil, a default client with 30-second timeout is created.
// When set, InsecureSkipVerify is ignored (configure TLS on your client's transport).
HTTPClient *http.Client
// Logger is the structured logger for debug output
// If nil, logging is disabled (default)
Logger Logger
// MaxRefDepth is the maximum depth for resolving nested $ref pointers.
// Default: 100
MaxRefDepth int
// MaxCachedDocuments is the maximum number of external documents to cache.
// Default: 100
MaxCachedDocuments int
// MaxFileSize is the maximum file size in bytes for external references.
// Default: 10MB
MaxFileSize int64
// MaxInputSize is the maximum input size in bytes for the primary document.
// Applies to ParseReader and ParseBytes. Default: 100 MiB
MaxInputSize int64
// BuildSourceMap enables source location tracking during parsing.
// When enabled, the ParseResult.SourceMap will contain line/column
// information for each JSON path in the document.
// Default: false
BuildSourceMap bool
// PreserveOrder enables order-preserving marshaling.
// When enabled, ParseResult stores the original yaml.Node structure,
// allowing MarshalOrderedJSON/MarshalOrderedYAML to emit fields
// in the same order as the source document.
// This is useful for hash-based caching where roundtrip identity matters.
// Default: false
PreserveOrder bool
}
Parser handles OpenAPI specification parsing
func (*Parser) Parse ¶
func (p *Parser) Parse(specPath string) (*ParseResult, error)
Parse parses an OpenAPI specification file or URL For URLs (http:// or https://), the content is fetched and parsed For local files, the file is read and parsed
func (*Parser) ParseBytes ¶
func (p *Parser) ParseBytes(data []byte) (*ParseResult, error)
ParseBytes parses an OpenAPI specification from a byte slice For external references to work, use Parse() with a file path instead Note: since there is no actual ParseResult.SourcePath, it will be set to: ParseBytes.yaml or ParseBytes.json
func (*Parser) ParseReader ¶
func (p *Parser) ParseReader(r io.Reader) (*ParseResult, error)
ParseReader parses an OpenAPI specification from an io.Reader Note: since there is no actual ParseResult.SourcePath, it will be set to: ParseReader.yaml or ParseReader.json
type PathItem ¶
type PathItem struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"` // OAS 3.0+
Description string `yaml:"description,omitempty" json:"description,omitempty"` // OAS 3.0+
Get *Operation `yaml:"get,omitempty" json:"get,omitempty"`
Put *Operation `yaml:"put,omitempty" json:"put,omitempty"`
Post *Operation `yaml:"post,omitempty" json:"post,omitempty"`
Delete *Operation `yaml:"delete,omitempty" json:"delete,omitempty"`
Options *Operation `yaml:"options,omitempty" json:"options,omitempty"`
Head *Operation `yaml:"head,omitempty" json:"head,omitempty"`
Patch *Operation `yaml:"patch,omitempty" json:"patch,omitempty"`
Trace *Operation `yaml:"trace,omitempty" json:"trace,omitempty"` // OAS 3.0+
Query *Operation `yaml:"query,omitempty" json:"query,omitempty"` // OAS 3.2+
Servers []*Server `yaml:"servers,omitempty" json:"servers,omitempty"` // OAS 3.0+
Parameters []*Parameter `yaml:"parameters,omitempty" json:"parameters,omitempty"`
// OAS 3.2+ additions
AdditionalOperations map[string]*Operation `yaml:"additionalOperations,omitempty" json:"additionalOperations,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
PathItem describes the operations available on a single path
func (*PathItem) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies PathItem into out.
func (*PathItem) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for PathItem. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*PathItem) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for PathItem. This captures unknown fields (specification extensions like x-*) in the Extra map.
type RefLocation ¶ added in v1.27.0
type RefLocation struct {
// Origin is where the $ref is written in the source
Origin SourceLocation
// Target is where the referenced content is defined
Target SourceLocation
// TargetRef is the $ref string value (e.g., "#/components/schemas/Pet")
TargetRef string
}
RefLocation tracks both where a $ref is defined and where it points. This enables precise error reporting for reference-related issues.
type RefResolver ¶
type RefResolver struct {
// SourceMap is the accumulated source map being built during resolution
// When non-nil, external file source maps are built and merged
SourceMap *SourceMap
// ExternalSourceMaps caches source maps for external documents
ExternalSourceMaps map[string]*SourceMap
// ShallowCopy controls whether resolved $ref content is deep-copied.
// When true, resolved content shares references with the original map,
// which is safe when the consumer creates independent struct copies
// (e.g., decodeDocumentFromMap). When false (default), every resolved
// $ref is deep-copied to prevent shared mutation.
ShallowCopy bool
// contains filtered or unexported fields
}
RefResolver handles $ref resolution in OpenAPI documents
func NewRefResolver ¶
func NewRefResolver(baseDir string, maxRefDepth, maxCachedDocs int, maxFileSize int64) *RefResolver
NewRefResolver creates a new reference resolver for local and file-based refs. The maxRefDepth, maxCachedDocs, and maxFileSize parameters configure resource limits. A value of 0 for any parameter means the corresponding package-level constant is used as the default.
func NewRefResolverWithHTTP ¶ added in v1.18.0
func NewRefResolverWithHTTP(baseDir, baseURL string, fetcher HTTPFetcher, maxRefDepth, maxCachedDocs int, maxFileSize int64) *RefResolver
NewRefResolverWithHTTP creates a reference resolver with HTTP/HTTPS support. The baseURL is used for resolving relative refs when the source is an HTTP URL. The fetcher function is called to retrieve content from HTTP/HTTPS URLs. The maxRefDepth, maxCachedDocs, and maxFileSize parameters configure resource limits. A value of 0 for any parameter means the corresponding package-level constant is used as the default.
func (*RefResolver) HasCircularRefs ¶ added in v1.20.2
func (r *RefResolver) HasCircularRefs() bool
HasCircularRefs returns whether the last call to ResolveAllRefs detected circular references. When true, the resolver left circular $ref strings in place (unresolved) while resolving all non-circular references normally. The resolved data does NOT contain Go pointer cycles and can be safely serialized.
func (*RefResolver) ResolveAllRefs ¶
func (r *RefResolver) ResolveAllRefs(doc map[string]any) error
ResolveAllRefs walks through the entire document and resolves all $ref references
func (*RefResolver) ResolveExternal ¶
func (r *RefResolver) ResolveExternal(ref string) (any, error)
ResolveExternal resolves external file references External refs are in the format: ./file.yaml#/path/to/component or file.yaml#/path/to/component
func (*RefResolver) ResolveHTTP ¶ added in v1.18.0
func (r *RefResolver) ResolveHTTP(ref string) (any, error)
ResolveHTTP resolves HTTP/HTTPS URL references HTTP refs are in the format: https://example.com/api.yaml#/components/schemas/Pet
func (*RefResolver) ResolveLocal ¶
ResolveLocal resolves local references within a document Local refs are in the format: #/path/to/component
func (*RefResolver) SetCacheTTL ¶ added in v1.33.2
func (r *RefResolver) SetCacheTTL(ttl time.Duration)
SetCacheTTL sets the time-to-live for cached HTTP documents. A positive duration enables TTL-based cache expiration. Zero (default) caches forever for backward compatibility. A negative duration disables caching entirely.
type Reference ¶
type Reference struct {
Ref string `yaml:"$ref" json:"$ref"`
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"` // OAS 3.1+
Description string `yaml:"description,omitempty" json:"description,omitempty"` // OAS 3.1+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Reference represents a JSON Reference ($ref)
func (*Reference) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Reference into out.
func (*Reference) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Reference. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Reference) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Reference. This captures unknown fields (specification extensions like x-*) in the Extra map.
type RequestBody ¶
type RequestBody struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Content map[string]*MediaType `yaml:"content,omitempty" json:"content,omitempty"`
Required bool `yaml:"required,omitempty" json:"required,omitempty"`
Extra map[string]any `yaml:",inline" json:"-"`
}
RequestBody describes a single request body (OAS 3.0+).
Content is tagged omitempty for the same reason as Parameter.Name: a $ref request body would otherwise serialize with a null content sibling.
func (*RequestBody) DeepCopy ¶ added in v1.20.0
func (in *RequestBody) DeepCopy() *RequestBody
DeepCopy creates a deep copy of RequestBody.
func (*RequestBody) DeepCopyInto ¶ added in v1.20.0
func (in *RequestBody) DeepCopyInto(out *RequestBody)
DeepCopyInto copies RequestBody into out.
func (*RequestBody) MarshalJSON ¶ added in v1.6.1
func (rb *RequestBody) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for RequestBody. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*RequestBody) UnmarshalJSON ¶ added in v1.6.1
func (rb *RequestBody) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for RequestBody. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Response ¶
type Response struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Headers map[string]*Header `yaml:"headers,omitempty" json:"headers,omitempty"`
Content map[string]*MediaType `yaml:"content,omitempty" json:"content,omitempty"` // OAS 3.0+
Links map[string]*Link `yaml:"links,omitempty" json:"links,omitempty"` // OAS 3.0+
// Summary is a short description of the response, alongside the longer
// Description (OAS 3.2+).
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"` // OAS 3.2+
// OAS 2.0 specific
Schema *Schema `yaml:"schema,omitempty" json:"schema,omitempty"` // OAS 2.0
Examples map[string]any `yaml:"examples,omitempty" json:"examples,omitempty"` // OAS 2.0
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Response describes a single response from an API Operation.
Description is tagged omitempty for the same reason as Parameter.Name: a $ref response would otherwise serialize with an empty description sibling.
func (*Response) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Response into out.
func (*Response) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Response. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Response) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Response. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Responses ¶
type Responses struct {
Default *Response `yaml:"default,omitempty" json:"default,omitempty"`
Codes map[string]*Response `yaml:",inline" json:"-"` // Handled by custom marshaler
}
Responses is a container for the expected responses of an operation
func (*Responses) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Responses into out.
func (*Responses) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Responses. This flattens the Codes map into the top-level JSON object, where each HTTP status code (e.g., "200", "404") or wildcard pattern (e.g., "2XX") becomes a direct field in the JSON output. The "default" response is also included at the top level if present.
func (*Responses) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Responses. This captures status code fields in the Codes map and validates that each status code is either a valid HTTP status code (e.g., "200", "404"), a wildcard pattern (e.g., "2XX"), or a specification extension (e.g., "x-custom"). Returns an error if an invalid status code is encountered.
func (*Responses) UnmarshalYAML ¶
UnmarshalYAML implements custom unmarshaling for Responses to validate status codes during parsing. This prevents invalid fields from being captured in the Codes map and provides clearer error messages.
type Schema ¶
type Schema struct {
// JSON Schema Core
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Schema string `yaml:"$schema,omitempty" json:"$schema,omitempty"` // JSON Schema Draft version
// Metadata
Title string `yaml:"title,omitempty" json:"title,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Default any `yaml:"default,omitempty" json:"default,omitempty"`
Examples []any `yaml:"examples,omitempty" json:"examples,omitempty"` // OAS 3.0+, JSON Schema Draft 2020-12
// Type validation
Type any `yaml:"type,omitempty" json:"type,omitempty"` // string or []string (OAS 3.1+)
Enum []any `yaml:"enum,omitempty" json:"enum,omitempty"`
Const any `yaml:"const,omitempty" json:"const,omitempty"` // JSON Schema Draft 2020-12
// Numeric validation
MultipleOf *float64 `yaml:"multipleOf,omitempty" json:"multipleOf,omitempty"`
Maximum *float64 `yaml:"maximum,omitempty" json:"maximum,omitempty"`
ExclusiveMaximum any `yaml:"exclusiveMaximum,omitempty" json:"exclusiveMaximum,omitempty"` // bool in OAS 2.0/3.0, number in 3.1+
Minimum *float64 `yaml:"minimum,omitempty" json:"minimum,omitempty"`
ExclusiveMinimum any `yaml:"exclusiveMinimum,omitempty" json:"exclusiveMinimum,omitempty"` // bool in OAS 2.0/3.0, number in 3.1+
// String validation
MaxLength *int `yaml:"maxLength,omitempty" json:"maxLength,omitempty"`
MinLength *int `yaml:"minLength,omitempty" json:"minLength,omitempty"`
Pattern string `yaml:"pattern,omitempty" json:"pattern,omitempty"`
// Array validation
Items any `yaml:"items,omitempty" json:"items,omitempty"` // *Schema or bool (OAS 3.1+)
PrefixItems []*Schema `yaml:"prefixItems,omitempty" json:"prefixItems,omitempty"` // JSON Schema Draft 2020-12
AdditionalItems any `yaml:"additionalItems,omitempty" json:"additionalItems,omitempty"` // *Schema or bool
UnevaluatedItems any `yaml:"unevaluatedItems,omitempty" json:"unevaluatedItems,omitempty"` // JSON Schema Draft 2020-12: *Schema or bool
MaxItems *int `yaml:"maxItems,omitempty" json:"maxItems,omitempty"`
MinItems *int `yaml:"minItems,omitempty" json:"minItems,omitempty"`
UniqueItems bool `yaml:"uniqueItems,omitempty" json:"uniqueItems,omitempty"`
Contains *Schema `yaml:"contains,omitempty" json:"contains,omitempty"` // JSON Schema Draft 2020-12
MaxContains *int `yaml:"maxContains,omitempty" json:"maxContains,omitempty"` // JSON Schema Draft 2020-12
MinContains *int `yaml:"minContains,omitempty" json:"minContains,omitempty"` // JSON Schema Draft 2020-12
// Object validation
Properties map[string]*Schema `yaml:"properties,omitempty" json:"properties,omitempty"`
PatternProperties map[string]*Schema `yaml:"patternProperties,omitempty" json:"patternProperties,omitempty"`
AdditionalProperties any `yaml:"additionalProperties,omitempty" json:"additionalProperties,omitempty"` // *Schema or bool
UnevaluatedProperties any `yaml:"unevaluatedProperties,omitempty" json:"unevaluatedProperties,omitempty"` // JSON Schema Draft 2020-12: *Schema or bool
Required []string `yaml:"required,omitempty" json:"required,omitempty"`
PropertyNames *Schema `yaml:"propertyNames,omitempty" json:"propertyNames,omitempty"` // JSON Schema Draft 2020-12
MaxProperties *int `yaml:"maxProperties,omitempty" json:"maxProperties,omitempty"`
MinProperties *int `yaml:"minProperties,omitempty" json:"minProperties,omitempty"`
DependentRequired map[string][]string `yaml:"dependentRequired,omitempty" json:"dependentRequired,omitempty"` // JSON Schema Draft 2020-12
DependentSchemas map[string]*Schema `yaml:"dependentSchemas,omitempty" json:"dependentSchemas,omitempty"` // JSON Schema Draft 2020-12
// Conditional schemas
If *Schema `yaml:"if,omitempty" json:"if,omitempty"` // JSON Schema Draft 2020-12, OAS 3.1+
Then *Schema `yaml:"then,omitempty" json:"then,omitempty"` // JSON Schema Draft 2020-12, OAS 3.1+
Else *Schema `yaml:"else,omitempty" json:"else,omitempty"` // JSON Schema Draft 2020-12, OAS 3.1+
// Schema composition
AllOf []*Schema `yaml:"allOf,omitempty" json:"allOf,omitempty"`
AnyOf []*Schema `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
OneOf []*Schema `yaml:"oneOf,omitempty" json:"oneOf,omitempty"`
Not *Schema `yaml:"not,omitempty" json:"not,omitempty"`
// OAS specific extensions
Nullable bool `yaml:"nullable,omitempty" json:"nullable,omitempty"` // OAS 3.0 only (replaced by type: [T, "null"] in 3.1+)
Discriminator *Discriminator `yaml:"discriminator,omitempty" json:"discriminator,omitempty"` // OAS 2.0+ (bare string in 2.0, object in 3.0+)
ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"` // OAS 2.0+
WriteOnly bool `yaml:"writeOnly,omitempty" json:"writeOnly,omitempty"` // OAS 3.0+
XML *XML `yaml:"xml,omitempty" json:"xml,omitempty"` // OAS 2.0+
ExternalDocs *ExternalDocs `yaml:"externalDocs,omitempty" json:"externalDocs,omitempty"` // OAS 2.0+
Example any `yaml:"example,omitempty" json:"example,omitempty"` // OAS 2.0, 3.0 (deprecated in 3.1+)
Deprecated bool `yaml:"deprecated,omitempty" json:"deprecated,omitempty"` // OAS 3.0+
// Format
Format string `yaml:"format,omitempty" json:"format,omitempty"` // e.g., "date-time", "email", "uri", etc.
// Content keywords (JSON Schema Draft 2020-12)
ContentEncoding string `yaml:"contentEncoding,omitempty" json:"contentEncoding,omitempty"` // e.g., "base64", "base32"
ContentMediaType string `yaml:"contentMediaType,omitempty" json:"contentMediaType,omitempty"` // e.g., "application/json"
ContentSchema *Schema `yaml:"contentSchema,omitempty" json:"contentSchema,omitempty"` // Schema for decoded content
// OAS 2.0 specific
CollectionFormat string `yaml:"collectionFormat,omitempty" json:"collectionFormat,omitempty"` // OAS 2.0
// JSON Schema Draft 2020-12 additional fields
ID string `yaml:"$id,omitempty" json:"$id,omitempty"`
Anchor string `yaml:"$anchor,omitempty" json:"$anchor,omitempty"`
DynamicRef string `yaml:"$dynamicRef,omitempty" json:"$dynamicRef,omitempty"`
DynamicAnchor string `yaml:"$dynamicAnchor,omitempty" json:"$dynamicAnchor,omitempty"`
Vocabulary map[string]bool `yaml:"$vocabulary,omitempty" json:"$vocabulary,omitempty"`
Comment string `yaml:"$comment,omitempty" json:"$comment,omitempty"`
Defs map[string]*Schema `yaml:"$defs,omitempty" json:"$defs,omitempty"`
// Extension fields
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Schema represents a JSON Schema Supports OAS 2.0, OAS 3.0, OAS 3.1+ (JSON Schema Draft 2020-12)
Example (Items) ¶
ExampleSchema_items demonstrates reading Schema's any-typed fields. Items, AdditionalProperties, AdditionalItems, UnevaluatedItems and UnevaluatedProperties hold either a *Schema or a bool per JSON Schema, so consumers type-assert. The decoded types are the same whether the source was YAML or JSON.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
)
func main() {
spec := []byte(`openapi: 3.0.3
info:
title: Inventory API
version: "1.0"
paths: {}
components:
schemas:
Tags:
type: array
items:
type: string
Counters:
type: object
additionalProperties:
type: integer
Strict:
type: object
additionalProperties: false
`)
result, err := parser.ParseWithOptions(parser.WithBytes(spec))
if err != nil {
log.Fatal(err)
}
doc, ok := result.OAS3Document()
if !ok {
log.Fatal("expected OAS3 document")
}
// Items is a *parser.Schema when present
items, ok := doc.Components.Schemas["Tags"].Items.(*parser.Schema)
if !ok {
log.Fatal("expected Items to be a schema")
}
fmt.Printf("Tags items: %v\n", items.Type)
// AdditionalProperties is either a *parser.Schema or a bool
for _, name := range []string{"Counters", "Strict"} {
switch additional := doc.Components.Schemas[name].AdditionalProperties.(type) {
case *parser.Schema:
fmt.Printf("%s additionalProperties: schema of %v\n", name, additional.Type)
case bool:
fmt.Printf("%s additionalProperties: %v\n", name, additional)
default:
fmt.Printf("%s additionalProperties: not set\n", name)
}
}
}
Output: Tags items: string Counters additionalProperties: schema of integer Strict additionalProperties: false
func (*Schema) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Schema into out.
func (*Schema) Equals ¶ added in v1.44.0
Equals compares two Schemas for structural equality. Returns true if both schemas have identical content. This method handles cyclic schema references safely.
Example ¶
ExampleSchema_Equals demonstrates comparing two Schema objects for structural equality. This is useful for detecting schema changes or deduplicating identical schemas.
package main
import (
"fmt"
"github.com/erraggy/oastools/parser"
)
func main() {
// Create two identical schemas
schema1 := &parser.Schema{
Type: "object",
Description: "A pet in the store",
Properties: map[string]*parser.Schema{
"id": {Type: "integer", Format: "int64"},
"name": {Type: "string"},
},
Required: []string{"id", "name"},
}
schema2 := &parser.Schema{
Type: "object",
Description: "A pet in the store",
Properties: map[string]*parser.Schema{
"id": {Type: "integer", Format: "int64"},
"name": {Type: "string"},
},
Required: []string{"id", "name"},
}
fmt.Printf("Schemas equal: %v\n", schema1.Equals(schema2))
// Modify one schema
schema2.Description = "A different description"
fmt.Printf("After modification: %v\n", schema1.Equals(schema2))
}
Output: Schemas equal: true After modification: false
func (*Schema) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Schema. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Schema) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Schema. This captures unknown fields (specification extensions like x-*) in the Extra map.
func (*Schema) UnmarshalYAML ¶ added in v1.57.0
UnmarshalYAML implements custom YAML unmarshaling for Schema.
The alias type sheds this method so default struct decoding (including the inline Extra map) applies, then the any-typed schema-or-bool fields are promoted to *Schema. Without the promotion the decoder leaves a nested mapping as map[string]any, and every consumer that type-asserts to *Schema silently skips the subtree: validation, $ref rewriting, and fixes inside `items:` would all no-op.
Schema.UnmarshalJSON does the same job for JSON, and decodeFromMap for the ResolveRefs path. All three must agree on the decoded types.
type SecurityRequirement ¶
SecurityRequirement lists the required security schemes to execute an operation Maps security scheme names to scopes (if applicable)
type SecurityScheme ¶
type SecurityScheme struct {
Ref string `yaml:"$ref,omitempty" json:"$ref,omitempty"`
Type string `yaml:"type" json:"type"` // "apiKey", "http", "oauth2", "openIdConnect" (OAS 3.0+), "basic", "apiKey", "oauth2" (OAS 2.0)
Description string `yaml:"description,omitempty" json:"description,omitempty"`
// Type: apiKey (OAS 2.0+, 3.0+)
Name string `yaml:"name,omitempty" json:"name,omitempty"` // Header, query, or cookie parameter name
In string `yaml:"in,omitempty" json:"in,omitempty"` // "query", "header", "cookie" (OAS 3.0+)
// Type: http (OAS 3.0+)
Scheme string `yaml:"scheme,omitempty" json:"scheme,omitempty"` // e.g., "basic", "bearer"
BearerFormat string `yaml:"bearerFormat,omitempty" json:"bearerFormat,omitempty"` // e.g., "JWT"
// Type: oauth2
Flows *OAuthFlows `yaml:"flows,omitempty" json:"flows,omitempty"` // OAS 3.0+
// Type: oauth2 (OAS 2.0)
Flow string `yaml:"flow,omitempty" json:"flow,omitempty"` // "implicit", "password", "application", "accessCode"
AuthorizationURL string `yaml:"authorizationUrl,omitempty" json:"authorizationUrl,omitempty"` // OAS 2.0
TokenURL string `yaml:"tokenUrl,omitempty" json:"tokenUrl,omitempty"` // OAS 2.0
Scopes map[string]string `yaml:"scopes,omitempty" json:"scopes,omitempty"` // OAS 2.0
// Type: openIdConnect (OAS 3.0+)
OpenIDConnectURL string `yaml:"openIdConnectUrl,omitempty" json:"openIdConnectUrl,omitempty"`
// Deprecated marks the scheme as no longer recommended for use (OAS 3.2+).
Deprecated bool `yaml:"deprecated,omitempty" json:"deprecated,omitempty"` // OAS 3.2+
// OAuth2MetadataURL points at the OAuth 2.0 Authorization Server Metadata
// document for the scheme (OAS 3.2+).
OAuth2MetadataURL string `yaml:"oauth2MetadataUrl,omitempty" json:"oauth2MetadataUrl,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
SecurityScheme defines a security scheme that can be used by the operations
func (*SecurityScheme) DeepCopy ¶ added in v1.20.0
func (in *SecurityScheme) DeepCopy() *SecurityScheme
DeepCopy creates a deep copy of SecurityScheme.
func (*SecurityScheme) DeepCopyInto ¶ added in v1.20.0
func (in *SecurityScheme) DeepCopyInto(out *SecurityScheme)
DeepCopyInto copies SecurityScheme into out.
func (*SecurityScheme) MarshalJSON ¶ added in v1.6.1
func (ss *SecurityScheme) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for SecurityScheme. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*SecurityScheme) UnmarshalJSON ¶ added in v1.6.1
func (ss *SecurityScheme) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for SecurityScheme. This captures unknown fields (specification extensions like x-*) in the Extra map.
type Server ¶
type Server struct {
URL string `yaml:"url" json:"url"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Variables map[string]ServerVariable `yaml:"variables,omitempty" json:"variables,omitempty"`
// Name is a short identifier for the server, unique among the servers of the
// document it appears in (OAS 3.2+).
Name string `yaml:"name,omitempty" json:"name,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Server represents a Server object (OAS 3.0+)
func (*Server) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Server into out.
func (*Server) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Server. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Server) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Server. This captures unknown fields (specification extensions like x-*) in the Extra map.
type ServerVariable ¶
type ServerVariable struct {
Enum []string `yaml:"enum,omitempty" json:"enum,omitempty"`
Default string `yaml:"default" json:"default"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
ServerVariable represents a Server Variable object (OAS 3.0+)
func (*ServerVariable) DeepCopy ¶ added in v1.20.0
func (in *ServerVariable) DeepCopy() *ServerVariable
DeepCopy creates a deep copy of ServerVariable.
func (*ServerVariable) DeepCopyInto ¶ added in v1.20.0
func (in *ServerVariable) DeepCopyInto(out *ServerVariable)
DeepCopyInto copies ServerVariable into out.
func (*ServerVariable) MarshalJSON ¶ added in v1.6.1
func (sv *ServerVariable) MarshalJSON() ([]byte, error)
MarshalJSON implements custom JSON marshaling for ServerVariable. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*ServerVariable) UnmarshalJSON ¶ added in v1.6.1
func (sv *ServerVariable) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for ServerVariable. This captures unknown fields (specification extensions like x-*) in the Extra map.
type SlogAdapter ¶ added in v1.21.0
type SlogAdapter struct {
// contains filtered or unexported fields
}
SlogAdapter wraps a *slog.Logger to implement the Logger interface. This allows using the standard library's slog package with oastools.
func NewSlogAdapter ¶ added in v1.21.0
func NewSlogAdapter(logger *slog.Logger) *SlogAdapter
NewSlogAdapter creates a new SlogAdapter from a *slog.Logger. If logger is nil, slog.Default() is used.
func (*SlogAdapter) Debug ¶ added in v1.21.0
func (s *SlogAdapter) Debug(msg string, attrs ...any)
Debug implements Logger.
func (*SlogAdapter) Error ¶ added in v1.21.0
func (s *SlogAdapter) Error(msg string, attrs ...any)
Error implements Logger.
func (*SlogAdapter) Info ¶ added in v1.21.0
func (s *SlogAdapter) Info(msg string, attrs ...any)
Info implements Logger.
func (*SlogAdapter) Warn ¶ added in v1.21.0
func (s *SlogAdapter) Warn(msg string, attrs ...any)
Warn implements Logger.
func (*SlogAdapter) With ¶ added in v1.21.0
func (s *SlogAdapter) With(attrs ...any) Logger
With implements Logger.
type SourceFormat ¶ added in v1.6.0
type SourceFormat string
SourceFormat represents the format of the source OpenAPI specification file
const ( // SourceFormatYAML indicates the source was in YAML format SourceFormatYAML SourceFormat = "yaml" // SourceFormatJSON indicates the source was in JSON format SourceFormatJSON SourceFormat = "json" // SourceFormatUnknown indicates the source format could not be determined SourceFormatUnknown SourceFormat = "unknown" )
type SourceLocation ¶ added in v1.27.0
type SourceLocation struct {
// Line is the 1-based line number (0 if unknown)
Line int
// Column is the 1-based column number (0 if unknown)
Column int
// File is the source file path (empty for the main document)
File string
}
SourceLocation represents a position in a source document. Line and Column are 1-based (matching editor conventions). A zero Line value indicates the location is unknown.
func (SourceLocation) IsKnown ¶ added in v1.27.0
func (s SourceLocation) IsKnown() bool
IsKnown returns true if this location has valid line information.
func (SourceLocation) String ¶ added in v1.27.0
func (s SourceLocation) String() string
String returns a human-readable location string. Format: "file:line:column" or "line:column" if no file, or "<unknown>" if not known.
type SourceMap ¶ added in v1.27.0
type SourceMap struct {
// contains filtered or unexported fields
}
SourceMap provides JSON path to source location mapping. It enables looking up the original source position for any element in a parsed OpenAPI document.
The SourceMap is built during parsing when WithSourceMap(true) is used. It uses JSON path notation for keys (e.g., "$.paths./users.get.responses.200").
func NewSourceMap ¶ added in v1.27.0
func NewSourceMap() *SourceMap
NewSourceMap creates an empty SourceMap.
func (*SourceMap) Copy ¶ added in v1.27.0
Copy creates a deep copy of the SourceMap. Returns nil if the receiver is nil.
func (*SourceMap) Get ¶ added in v1.27.0
func (sm *SourceMap) Get(path string) SourceLocation
Get returns the source location for a JSON path. Returns a zero SourceLocation if the path is not found.
func (*SourceMap) GetKey ¶ added in v1.27.0
func (sm *SourceMap) GetKey(path string) SourceLocation
GetKey returns the source location of a map key at the given path. This is useful for errors about the key itself (e.g., "unknown field"). Returns a zero SourceLocation if the path is not found.
func (*SourceMap) GetRef ¶ added in v1.27.0
func (sm *SourceMap) GetRef(path string) RefLocation
GetRef returns the reference location information for a path containing a $ref. Returns a zero RefLocation if no $ref exists at the path.
type Tag ¶
type Tag struct {
Name string `yaml:"name" json:"name"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
ExternalDocs *ExternalDocs `yaml:"externalDocs,omitempty" json:"externalDocs,omitempty"`
// Summary is a short display name for the tag (OAS 3.2+).
Summary string `yaml:"summary,omitempty" json:"summary,omitempty"` // OAS 3.2+
// Parent names another tag this one nests under, forming a tag hierarchy
// (OAS 3.2+). The value is a tag name, not a reference.
Parent string `yaml:"parent,omitempty" json:"parent,omitempty"` // OAS 3.2+
// Kind classifies how tooling should treat the tag, e.g. "nav" or "badge"
// (OAS 3.2+).
Kind string `yaml:"kind,omitempty" json:"kind,omitempty"` // OAS 3.2+
// Extra captures specification extensions (fields starting with "x-")
Extra map[string]any `yaml:",inline" json:"-"`
}
Tag adds metadata to a single tag used by operations
func (*Tag) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies Tag into out.
func (*Tag) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for Tag. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*Tag) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for Tag. This captures unknown fields (specification extensions like x-*) in the Extra map.
type XML ¶
type XML struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"`
Attribute bool `yaml:"attribute,omitempty" json:"attribute,omitempty"`
Wrapped bool `yaml:"wrapped,omitempty" json:"wrapped,omitempty"`
// NodeType selects the XML node a schema maps to, superseding Attribute and
// Wrapped (OAS 3.2+).
// https://spec.openapis.org/oas/v3.2.0.html#xml-node-type
//
// Deliberately independent of those two bools rather than reconciled with them.
// Its default depends on the enclosing Schema Object, which an XML Object cannot
// see, so deriving a value here would invent one the document never stated.
// Keeping them independent lets each survive a round trip as written; the spec
// forbids setting both, and the validator enforces that.
NodeType string `yaml:"nodeType,omitempty" json:"nodeType,omitempty"` // OAS 3.2+
Extra map[string]any `yaml:",inline" json:"-"`
}
XML represents metadata for XML encoding (OAS 2.0+) https://spec.openapis.org/oas/v3.2.0.html#xml-object
NodeType supersedes Attribute and Wrapped in OAS 3.2 and is modeled beside them rather than derived from either. See the field's own comment for why.
func (*XML) DeepCopyInto ¶ added in v1.20.0
DeepCopyInto copies XML into out.
func (*XML) MarshalJSON ¶ added in v1.6.1
MarshalJSON implements custom JSON marshaling for XML. This is required to flatten Extra fields (specification extensions like x-*) into the top-level JSON object, as Go's encoding/json doesn't support inline maps like yaml:",inline".
func (*XML) UnmarshalJSON ¶ added in v1.6.1
UnmarshalJSON implements custom JSON unmarshaling for XML. This captures unknown fields (specification extensions like x-*) in the Extra map.
Source Files
¶
- common.go
- common_equals.go
- common_json.go
- constants.go
- decode.go
- decode_helpers.go
- deepcopy_helpers.go
- doc.go
- document_equals.go
- equals.go
- interfaces.go
- logger.go
- oas2.go
- oas2_json.go
- oas3.go
- oas3_json.go
- operations.go
- ordered_marshal.go
- parameters.go
- parameters_equals.go
- parameters_json.go
- parser.go
- parser_format.go
- parser_options.go
- paths.go
- paths_equals.go
- paths_json.go
- pool.go
- resolver.go
- schema.go
- schema_equals.go
- schema_json.go
- schema_yaml.go
- security.go
- security_equals.go
- security_json.go
- semver.go
- sourcemap.go
- stats.go
- versions.go
- zz_generated_decode.go
- zz_generated_deepcopy.go
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
jsonhelpers
Package jsonhelpers provides helper functions for JSON marshaling and unmarshaling with support for extension fields (x-* properties) in OpenAPI specifications.
|
Package jsonhelpers provides helper functions for JSON marshaling and unmarshaling with support for extension fields (x-* properties) in OpenAPI specifications. |