Documentation
¶
Overview ¶
Package validator provides validation for OpenAPI Specification documents.
The validator supports OAS 2.0 through OAS 3.2.0, performing structural validation, format checking, and semantic analysis against the specification requirements. It includes best practice warnings and strict mode for enhanced validation.
Quick Start ¶
Validate a file with warnings enabled using functional options:
result, err := validator.ValidateWithOptions(
validator.WithFilePath("openapi.yaml"),
validator.WithIncludeWarnings(true),
)
if err != nil {
log.Fatal(err)
}
if !result.Valid {
fmt.Printf("Found %d error(s)\n", result.ErrorCount)
}
Or create a reusable validator instance:
v := validator.New()
v.StrictMode = true
result, _ := v.Validate("api1.yaml")
result, _ := v.Validate("api2.yaml")
Features ¶
The validator checks document structure, required fields, format validation (URLs, emails, media types), semantic constraints (operation ID uniqueness, parameter consistency), and JSON schemas. Path validation includes checking for malformed templates (unclosed braces, reserved characters, consecutive slashes) and REST best practices (trailing slashes generate warnings when IncludeWarnings is enabled). See the examples in example_test.go for more usage patterns.
Validation Output ¶
ValidationResult contains:
- Valid: Boolean indicating if document is valid
- Version: Detected OpenAPI version (e.g., "3.0.3")
- Errors: Validation errors with JSON path locations and optional OperationContext
- Warnings: Best practice warnings (if IncludeWarnings is true)
- ErrorCount, WarningCount: Issue counts
- Document: The validated document for chaining with other packages
Each ValidationError includes an OperationContext field that identifies the affected API operation (HTTP method, path, operationId). This helps pinpoint which endpoint contains the error. See Example_operationContext for usage.
See the exported ValidationError and ValidationResult types for complete details.
Package Chaining with ToParseResult ¶
The ValidationResult.ToParseResult() method enables chaining validation with other oastools packages. This converts the validation result back to a ParseResult that can be passed to fixer, converter, joiner, or differ:
// Parse and validate, then fix any issues
parseResult, _ := parser.ParseWithOptions(parser.WithFilePath("api.yaml"))
valResult, _ := validator.ValidateWithOptions(validator.WithParsed(*parseResult))
if !valResult.Valid {
fixResult, _ := fixer.FixWithOptions(fixer.WithParsed(*valResult.ToParseResult()))
// Use fixResult...
}
Validation errors and warnings are converted to string warnings in the ParseResult with severity prefixes for programmatic filtering:
- "[error] path: message" for validation errors
- "[warning] path: message" for validation warnings
Related Packages ¶
Validation typically follows parsing:
- github.com/erraggy/oastools/parser - Parse specifications before validation
- github.com/erraggy/oastools/fixer - Fix common validation errors automatically
- github.com/erraggy/oastools/converter - Convert validated specs between OAS versions
- github.com/erraggy/oastools/joiner - Join validated specs into one document
- github.com/erraggy/oastools/differ - Compare specifications and detect breaking changes
- github.com/erraggy/oastools/generator - Generate Go code from validated specifications
- github.com/erraggy/oastools/builder - Programmatically build specifications
Example (CustomValidation) ¶
Example_customValidation demonstrates how to use the validator with custom options for best practice warnings and strict validation.
package main
import (
"fmt"
"log"
"path/filepath"
"github.com/erraggy/oastools/validator"
)
func main() {
// Create a validator with strict mode and warnings enabled
v := validator.New()
v.IncludeWarnings = true // Include best-practice warnings
v.StrictMode = true // Enforce strict validation rules
// Validate an OpenAPI specification
testFile := filepath.Join("testdata", "petstore-3.0.yaml")
result, err := v.Validate(testFile)
if err != nil {
log.Fatal(err)
}
// Separate errors from warnings by severity
errors := 0
warnings := 0
for _, issue := range result.Errors {
// Severity levels: SeverityCritical=3, SeverityError=2, SeverityWarning=1, SeverityInfo=0
switch issue.Severity {
case validator.SeverityCritical:
errors++ // Critical issues are also errors
fmt.Printf("CRITICAL [%s]: %s\n", issue.Path, issue.Message)
case validator.SeverityError:
errors++
fmt.Printf("ERROR [%s]: %s\n", issue.Path, issue.Message)
case validator.SeverityWarning:
warnings++
fmt.Printf("WARNING [%s]: %s\n", issue.Path, issue.Message)
case validator.SeverityInfo:
fmt.Printf("INFO [%s]: %s\n", issue.Path, issue.Message)
}
}
// Summary
fmt.Printf("\nValidation complete:\n")
fmt.Printf("- Valid: %v\n", result.Valid)
fmt.Printf("- Errors: %d\n", errors)
fmt.Printf("- Warnings: %d\n", warnings)
// StrictMode treats warnings as errors for result.Valid
// IncludeWarnings populates result.Errors with warning-level issues
}
Example (OperationContext) ¶
Example_operationContext demonstrates how validation errors include operation context to help identify which API operation an error relates to. This is especially useful for errors in shared components (schemas, responses) that are referenced by multiple operations.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
"github.com/erraggy/oastools/validator"
)
func main() {
// A spec with a validation error in an operation
spec := `
openapi: 3.0.0
info:
title: Test API
version: 1.0.0
paths:
/users/{userId}:
get:
operationId: getUser
parameters:
- name: wrongName
in: path
required: true
schema:
type: string
responses:
'200':
description: Success
`
parseResult, err := parser.ParseWithOptions(parser.WithBytes([]byte(spec)))
if err != nil {
log.Fatal(err)
}
result, err := validator.ValidateWithOptions(
validator.WithParsed(*parseResult),
)
if err != nil {
log.Fatal(err)
}
// Validation errors include operation context
for _, e := range result.Errors {
// The String() method includes operation context automatically
fmt.Println(e.String())
// You can also access the OperationContext programmatically
if e.OperationContext != nil {
fmt.Printf(" Operation: %s %s\n", e.OperationContext.Method, e.OperationContext.Path)
if e.OperationContext.OperationID != "" {
fmt.Printf(" OperationId: %s\n", e.OperationContext.OperationID)
}
}
}
}
Output: ✗ paths./users/{userId}.get (operationId: getUser): Path template references parameter '{userId}' but it is not declared in parameters Spec: https://spec.openapis.org/oas/v3.0.0.html#path-item-object Operation: GET /users/{userId} OperationId: getUser
Example (ToParseResult) ¶
Example_toParseResult demonstrates using ToParseResult for package chaining. This pattern allows validated documents to be passed to other oastools packages.
package main
import (
"fmt"
"log"
"path/filepath"
"github.com/erraggy/oastools/validator"
)
func main() {
// Validate a specification
v := validator.New()
testFile := filepath.Join("testdata", "petstore-3.0.yaml")
result, err := v.Validate(testFile)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Valid: %v\n", result.Valid)
// Convert to ParseResult for use with other packages
parseResult := result.ToParseResult()
fmt.Printf("SourcePath: %s\n", parseResult.SourcePath)
fmt.Printf("Version: %s\n", parseResult.Version)
// The ParseResult can now be passed to fixer, converter, joiner, etc.
// For example:
// fixResult, _ := fixer.FixWithOptions(fixer.WithParsed(*parseResult))
// convertResult, _ := converter.ConvertWithOptions(converter.WithParsed(*parseResult), ...)
}
Index ¶
- Constants
- type Option
- func WithFilePath(path string) Option
- func WithIncludeWarnings(enabled bool) Option
- func WithParsed(result parser.ParseResult) Option
- func WithSourceMap(sm *parser.SourceMap) Option
- func WithStrictMode(enabled bool) Option
- func WithUserAgent(ua string) Option
- func WithValidateStructure(enabled bool) Option
- type Severity
- type ValidationError
- type ValidationResult
- type Validator
Examples ¶
Constants ¶
const ( // SeverityError indicates a spec violation that makes the document invalid SeverityError = severity.SeverityError // SeverityWarning indicates a best practice violation or recommendation SeverityWarning = severity.SeverityWarning // SeverityInfo indicates informational messages SeverityInfo = severity.SeverityInfo // SeverityCritical indicates critical issues SeverityCritical = severity.SeverityCritical )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Option ¶ added in v1.11.0
type Option func(*validateConfig) error
Option is a function that configures a validation operation
func WithFilePath ¶ added in v1.11.0
WithFilePath specifies a file path or URL as the input source
func WithIncludeWarnings ¶ added in v1.11.0
WithIncludeWarnings enables or disables best practice warnings Default: true
func WithParsed ¶ added in v1.11.0
func WithParsed(result parser.ParseResult) Option
WithParsed specifies a parsed ParseResult as the input source
func WithSourceMap ¶ added in v1.27.0
WithSourceMap provides a SourceMap for populating line/column information in validation errors. The SourceMap is typically obtained from parsing with parser.WithSourceMap(true).
func WithStrictMode ¶ added in v1.11.0
WithStrictMode enables or disables strict validation beyond spec requirements Default: false
func WithUserAgent ¶ added in v1.11.0
WithUserAgent sets the User-Agent string for HTTP requests Default: "" (uses parser default)
func WithValidateStructure ¶ added in v1.42.0
WithValidateStructure enables or disables parser structure validation. When enabled (default), the parser validates required fields and correct types. When disabled, parsing is more lenient and skips structure validation. Default: true
type ValidationError ¶
ValidationError represents a single validation issue
type ValidationResult ¶
type ValidationResult struct {
// Valid is true if no errors were found (warnings are allowed)
Valid bool
// Version is the detected OAS version string
Version string
// OASVersion is the enumerated OAS version
OASVersion parser.OASVersion
// Errors contains all validation errors
Errors []ValidationError
// Warnings contains all validation warnings
Warnings []ValidationError
// ErrorCount is the total number of errors
ErrorCount int
// WarningCount is the total number of warnings
WarningCount int
// LoadTime is the time taken to load the source data
LoadTime time.Duration
// SourceSize is the size of the source data in bytes
SourceSize int64
// Stats contains statistical information about the document
Stats parser.DocumentStats
// Document contains the validated document (*parser.OAS2Document or *parser.OAS3Document).
// Added to enable ToParseResult() for package chaining.
Document any
// SourceFormat is the format of the source file (JSON or YAML)
SourceFormat parser.SourceFormat
// SourcePath is the original source path from the parsed document.
// Used by ToParseResult() to preserve the original path for package chaining.
SourcePath string
}
ValidationResult contains the results of validating an OpenAPI specification
func ValidateWithOptions ¶ added in v1.11.0
func ValidateWithOptions(opts ...Option) (*ValidationResult, error)
ValidateWithOptions validates 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 := validator.ValidateWithOptions(
validator.WithFilePath("openapi.yaml"),
validator.WithStrictMode(true),
)
Example (ValidateStructure) ¶
ExampleValidateWithOptions_validateStructure demonstrates the functional option for controlling parser structure validation.
package main
import (
"fmt"
"log"
"github.com/erraggy/oastools/parser"
"github.com/erraggy/oastools/validator"
)
func main() {
// A valid OpenAPI spec to test with
spec := `
openapi: 3.0.0
info:
title: Test API
version: 1.0.0
paths:
/users:
get:
operationId: listUsers
responses:
'200':
description: Success
`
// Parse the spec first
parseResult, err := parser.ParseWithOptions(parser.WithBytes([]byte(spec)))
if err != nil {
log.Fatal(err)
}
// Validate with structure validation disabled using functional options
result, err := validator.ValidateWithOptions(
validator.WithParsed(*parseResult),
validator.WithValidateStructure(false),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Valid: %v\n", result.Valid)
}
Output: Valid: true
func (*ValidationResult) ToParseResult ¶ added in v1.41.0
func (r *ValidationResult) ToParseResult() *parser.ParseResult
ToParseResult converts the ValidationResult to a ParseResult for use with other packages like fixer, converter, joiner, and differ. The returned ParseResult has Document populated but Data is nil (consumers use Document, not Data). Validation errors and warnings are converted to string warnings with severity prefixes for programmatic filtering: "[error] path: message", "[warning] path: message", etc.
type Validator ¶
type Validator struct {
// IncludeWarnings determines whether to include best practice warnings
IncludeWarnings bool
// StrictMode enables stricter validation beyond the spec requirements
StrictMode bool
// ValidateStructure controls whether the parser performs basic structure validation.
// When true (default), the parser validates required fields and correct types.
// When false, parsing is more lenient and skips structure validation.
ValidateStructure bool
// UserAgent is the User-Agent string used when fetching URLs
// Defaults to "oastools" if not set
UserAgent string
// SourceMap provides source location lookup for validation errors.
// When set, validation errors will include Line, Column, and File fields.
SourceMap *parser.SourceMap
// contains filtered or unexported fields
}
Validator handles OpenAPI specification validation
func (*Validator) Validate ¶
func (v *Validator) Validate(specPath string) (*ValidationResult, error)
Validate validates an OpenAPI specification file
Example ¶
ExampleValidator_Validate demonstrates basic validation of an OpenAPI specification
package main
import (
"fmt"
"log"
"path/filepath"
"github.com/erraggy/oastools/validator"
)
func main() {
v := validator.New()
testFile := filepath.Join("testdata", "petstore-3.0.yaml")
result, err := v.Validate(testFile)
if err != nil {
log.Fatalf("Validation failed: %v", err)
}
fmt.Printf("Valid: %v\n", result.Valid)
fmt.Printf("Version: %s\n", result.Version)
fmt.Printf("Errors: %d\n", result.ErrorCount)
fmt.Printf("Warnings: %d\n", result.WarningCount)
}
Example (StrictMode) ¶
ExampleValidator_Validate_strictMode demonstrates validation with strict mode enabled
package main
import (
"fmt"
"log"
"path/filepath"
"github.com/erraggy/oastools/validator"
)
func main() {
v := validator.New()
v.StrictMode = true
testFile := filepath.Join("testdata", "petstore-3.0.yaml")
result, err := v.Validate(testFile)
if err != nil {
log.Fatalf("Validation failed: %v", err)
}
fmt.Printf("Valid: %v\n", result.Valid)
fmt.Printf("Errors: %d\n", result.ErrorCount)
fmt.Printf("Warnings: %d\n", result.WarningCount)
}
func (*Validator) ValidateParsed ¶ added in v1.3.1
func (v *Validator) ValidateParsed(parseResult parser.ParseResult) (*ValidationResult, error)
ValidateParsed validates an already parsed OpenAPI specification