Documentation
¶
Overview ¶
Example (Applying) ¶
Example_applying demonstrates how to apply an overlay to an OpenAPI document. Shows loading an overlay specification and applying it to transform an OpenAPI document.
// Create temporary files for this example
overlayContent := `overlay: 1.0.0
info:
title: Pet Store Enhancement Overlay
version: 1.0.0
actions:
- target: $.info.description
update: Enhanced pet store API with additional features`
openAPIContent := `openapi: 3.1.0
info:
title: Pet Store API
version: 1.0.0
description: A simple pet store API
paths:
/pets:
get:
summary: List pets
responses:
'200':
description: A list of pets`
// Write temporary files
overlayFile := "temp_overlay.yaml"
openAPIFile := "temp_openapi.yaml"
if err := os.WriteFile(overlayFile, []byte(overlayContent), 0644); err != nil {
panic(err)
}
if err := os.WriteFile(openAPIFile, []byte(openAPIContent), 0644); err != nil {
panic(err)
}
defer os.Remove(overlayFile)
defer os.Remove(openAPIFile)
// Parse the overlay
overlayDoc, err := overlay.Parse(overlayFile)
if err != nil {
panic(err)
}
// Load the OpenAPI document
openAPINode, err := loader.LoadSpecification(openAPIFile)
if err != nil {
panic(err)
}
// Apply the overlay to the OpenAPI document
err = overlayDoc.ApplyTo(openAPINode)
if err != nil {
panic(err)
}
// Convert back to YAML string
var buf strings.Builder
encoder := yaml.NewEncoder(&buf)
encoder.SetIndent(2)
err = encoder.Encode(openAPINode)
if err != nil {
panic(err)
}
fmt.Printf("Transformed document:\n%s", buf.String())
Output: Transformed document: openapi: 3.1.0 info: title: Pet Store API version: 1.0.0 description: Enhanced pet store API with additional features paths: /pets: get: summary: List pets responses: '200': description: A list of pets
Example (Creating) ¶
Example_creating demonstrates how to create an overlay specification programmatically. Shows building an overlay specification with update and remove actions.
// Create update value as yaml.Node
var updateNode yaml.Node
updateNode.SetString("Enhanced API with additional features")
// Create an overlay with update and remove actions
overlayDoc := &overlay.Overlay{
Version: "1.0.0",
Info: overlay.Info{
Title: "API Enhancement Overlay",
Version: "1.0.0",
},
Actions: []overlay.Action{
{
Target: "$.info.description",
Update: updateNode,
},
{
Target: "$.paths['/deprecated-endpoint']",
Remove: true,
},
},
}
result, err := overlayDoc.ToString()
if err != nil {
panic(err)
}
fmt.Printf("Overlay specification:\n%s", result)
Output: Overlay specification: overlay: 1.0.0 info: title: API Enhancement Overlay version: 1.0.0 actions: - target: $.info.description update: Enhanced API with additional features - target: $.paths['/deprecated-endpoint'] remove: true
Example (Parsing) ¶
Example_parsing demonstrates how to parse an overlay specification from a file. Shows loading an overlay file and accessing its properties.
package main
import (
"fmt"
"os"
"github.com/speakeasy-api/openapi/overlay"
)
func main() {
overlayContent := `overlay: 1.0.0
info:
title: API Modification Overlay
version: 1.0.0
actions:
- target: $.info.title
update: Enhanced Pet Store API
- target: $.info.version
update: 2.0.0`
// Write temporary file
overlayFile := "temp_overlay.yaml"
if err := os.WriteFile(overlayFile, []byte(overlayContent), 0644); err != nil {
panic(err)
}
defer func() { _ = os.Remove(overlayFile) }()
overlayDoc, err := overlay.Parse(overlayFile)
if err != nil {
panic(err)
}
fmt.Printf("Overlay Version: %s\n", overlayDoc.Version)
fmt.Printf("Title: %s\n", overlayDoc.Info.Title)
fmt.Printf("Number of Actions: %d\n", len(overlayDoc.Actions))
for i, action := range overlayDoc.Actions {
fmt.Printf("Action %d Target: %s\n", i+1, action.Target)
}
}
Output: Overlay Version: 1.0.0 Title: API Modification Overlay Number of Actions: 2 Action 1 Target: $.info.title Action 2 Target: $.info.version
Example (Removing) ¶
Example_removing demonstrates how to use remove actions in overlays. Shows removing specific paths and properties from an OpenAPI document.
// Sample OpenAPI document with endpoints to remove
openAPIContent := `openapi: 3.1.0
info:
title: API
version: 1.0.0
paths:
/users:
get:
summary: List users
/users/{id}:
get:
summary: Get user
/admin:
get:
summary: Admin endpoint
deprecated: true`
// Overlay to remove deprecated endpoints
overlayContent := `overlay: 1.0.0
info:
title: Cleanup Overlay
version: 1.0.0
actions:
- target: $.paths['/admin']
remove: true`
// Write temporary files
openAPIFile := "temp_openapi.yaml"
overlayFile := "temp_overlay.yaml"
if err := os.WriteFile(openAPIFile, []byte(openAPIContent), 0644); err != nil {
panic(err)
}
if err := os.WriteFile(overlayFile, []byte(overlayContent), 0644); err != nil {
panic(err)
}
defer func() { _ = os.Remove(openAPIFile) }()
defer func() { _ = os.Remove(overlayFile) }()
overlayDoc, err := overlay.Parse(overlayFile)
if err != nil {
panic(err)
}
openAPINode, err := loader.LoadSpecification(openAPIFile)
if err != nil {
panic(err)
}
err = overlayDoc.ApplyTo(openAPINode)
if err != nil {
panic(err)
}
var buf strings.Builder
encoder := yaml.NewEncoder(&buf)
encoder.SetIndent(2)
err = encoder.Encode(openAPINode)
if err != nil {
panic(err)
}
fmt.Printf("Document after removing deprecated endpoint:\n%s", buf.String())
Output: Document after removing deprecated endpoint: openapi: 3.1.0 info: title: API version: 1.0.0 paths: /users: get: summary: List users /users/{id}: get: summary: Get user
Example (Validating) ¶
Example_validating demonstrates how to validate an overlay specification. Shows loading and validating an overlay specification for correctness.
package main
import (
"fmt"
"os"
"github.com/speakeasy-api/openapi/overlay"
)
func main() {
// Invalid overlay specification (missing required fields)
invalidOverlay := `overlay: 1.0.0
info:
title: Invalid Overlay
actions:
- target: $.info.title
description: Missing update or remove`
// Write temporary file
overlayFile := "temp_invalid_overlay.yaml"
if err := os.WriteFile(overlayFile, []byte(invalidOverlay), 0644); err != nil {
panic(err)
}
defer func() { _ = os.Remove(overlayFile) }()
overlayDoc, err := overlay.Parse(overlayFile)
if err != nil {
fmt.Printf("Parse error: %s\n", err.Error())
return
}
validationErr := overlayDoc.Validate()
if validationErr != nil {
fmt.Println("Validation errors:")
fmt.Printf(" %s\n", validationErr.Error())
} else {
fmt.Println("Overlay specification is valid!")
}
}
Output: Validation errors: overlay info version must be defined
Index ¶
- Constants
- Variables
- func Format(path string) error
- func NewTargetSelector(path, method string) string
- func Upgrade(_ context.Context, o *Overlay, opts ...Option[UpgradeOptions]) (bool, error)
- type Action
- type Extensions
- type Info
- type Option
- type Overlay
- func (o *Overlay) ApplyTo(root *yaml.Node) error
- func (o *Overlay) ApplyToStrict(root *yaml.Node) ([]string, error)
- func (o *Overlay) Format(w io.Writer) error
- func (o *Overlay) NewPath(target string, warnings *[]string) (Queryable, error)
- func (o *Overlay) ToString() (string, error)
- func (o *Overlay) UsesRFC9535() bool
- func (o *Overlay) Validate() error
- func (o *Overlay) ValidateVersion() []error
- type Queryable
- type UpgradeOptions
- type ValidationErrors
Examples ¶
Constants ¶
const ( // LatestVersion is the latest supported overlay version LatestVersion = "1.1.0" // Version100 is the Overlay 1.0.0 version Version100 = "1.0.0" // Version110 is the Overlay 1.1.0 version Version110 = "1.1.0" )
Version constants for the Overlay specification
const ( // JSONPathRFC9535 enables RFC 9535 JSONPath implementation JSONPathRFC9535 = "rfc9535" // JSONPathLegacy enables legacy yamlpath implementation (for backward compatibility) JSONPathLegacy = "legacy" )
JSONPath implementation constants
Variables ¶
var ( ErrOverlayVersionInvalid = errors.New("overlay version is invalid") ErrOverlayVersionNotSupported = fmt.Errorf("overlay version must be one of: %s", strings.Join(sliceutil.Map(SupportedVersions, func(v *version.Version) string { return v.String() }), ", ")) ErrOverlayVersionMustBeDefined = errors.New("overlay version must be defined") ErrOverlayInfoTitleMustBeDefined = errors.New("overlay info title must be defined") ErrOverlayInfoVersionMustBeDefined = errors.New("overlay info version must be defined") ErrOverlayExtendsMustBeAValidURL = errors.New("overlay extends must be a valid URL") ErrOverlayMustDefineAtLeastOneAction = errors.New("overlay must define at least one action") ErrOverlayActionTargetMustBeDefined = errors.New("overlay action target must be defined") ErrOverlayActionRemoveAndUpdateCannotBeSet = errors.New("overlay action remove and update cannot be set") )
Errors
Functions ¶
func NewTargetSelector ¶
func Upgrade ¶ added in v1.15.0
Upgrade upgrades an Overlay document from 1.0.0 to the latest version (1.1.0). Returns true if an upgrade was performed, false if no upgrade was needed.
The upgrade process:
- Updates the overlay version field from 1.0.0 to 1.1.0
- Enables RFC 9535 JSONPath as the default implementation
- Clears redundant x-speakeasy-jsonpath: rfc9535 (now default in 1.1.0)
- All existing actions remain valid and functional
Note: The upgrade is non-destructive. All 1.0.0 features continue to work in 1.1.0.
Types ¶
type Action ¶
type Action struct {
Extensions `yaml:"-,inline"`
// Target is the JSONPath to the target of the action.
Target string `yaml:"target"`
// Description is a description of the action.
Description string `yaml:"description,omitempty"`
// Update is the sub-document to use to merge or replace in the target. This is
// ignored if Remove is set.
Update yaml.Node `yaml:"update,omitempty"`
// Remove marks the target node for removal rather than update.
Remove bool `yaml:"remove,omitempty"`
// Copy is a JSONPath to the source node to copy to the target. This is
// mutually exclusive with Update and Remove.
Copy string `yaml:"copy,omitempty"`
}
type Extensions ¶
Extensible provides a place for extensions to be added to components of the Overlay configuration. These are a map from x-* extension fields to their values.
type Info ¶
type Info struct {
Extensions `yaml:"-,inline"`
// Title is the title of the overlay.
Title string `yaml:"title"`
// Version is the version of the overlay.
Version string `yaml:"version"`
// Description is an optional description of the overlay (new in Overlay 1.1.0).
Description string `yaml:"description,omitempty"`
}
Info describes the metadata for the overlay.
type Option ¶ added in v1.15.0
type Option[T any] func(*T)
Option is a functional option for configuring behavior
func WithUpgradeTargetVersion ¶ added in v1.15.0
func WithUpgradeTargetVersion(ver string) Option[UpgradeOptions]
WithUpgradeTargetVersion sets the target version for the upgrade. If not specified, defaults to the latest supported version (1.1.0).
type Overlay ¶
type Overlay struct {
Extensions `yaml:"-,inline"`
// Version is the version of the overlay configuration (1.0.0 or 1.1.0)
Version string `yaml:"overlay"`
// JSONPathVersion controls the JSONPath implementation used.
// For version 1.0.0: default is legacy, use "rfc9535" to opt-in to RFC 9535
// For version 1.1.0: default is RFC 9535, use "legacy" to opt-out
JSONPathVersion string `yaml:"x-speakeasy-jsonpath,omitempty"`
// Info describes the metadata for the overlay.
Info Info `yaml:"info"`
// Extends is a URL to the OpenAPI specification this overlay applies to.
Extends string `yaml:"extends,omitempty"`
// Actions is the list of actions to perform to apply the overlay.
Actions []Action `yaml:"actions"`
}
Overlay is the top-level configuration for an OpenAPI overlay.
func Compare ¶
Compare compares input specifications from two files and returns an overlay that will convert the first into the second.
func (*Overlay) ApplyTo ¶
ApplyTo will take an overlay and apply its changes to the given YAML document.
func (*Overlay) NewPath ¶
NewPath creates a new JSONPath queryable from the given target expression. The implementation used depends on the overlay version and JSONPathVersion setting: - For version 1.0.0: Legacy yamlpath by default, opt-IN to RFC 9535 via "rfc9535" - For version 1.1.0+: RFC 9535 by default, opt-OUT to legacy via "legacy"
func (*Overlay) UsesRFC9535 ¶
UsesRFC9535 determines if the overlay should use RFC 9535 JSONPath implementation.
The behavior depends on the overlay version:
- For version 1.0.x: RFC 9535 is opt-IN (default is legacy)
- Set JSONPathVersion to "rfc9535" to enable RFC 9535
- For version 1.1.0+: RFC 9535 is the DEFAULT (opt-OUT available)
- Set JSONPathVersion to "legacy" to use legacy implementation
Explicit settings always take precedence over version-based defaults.
func (*Overlay) ValidateVersion ¶ added in v1.12.1
type UpgradeOptions ¶ added in v1.15.0
type UpgradeOptions struct {
// contains filtered or unexported fields
}
UpgradeOptions configures the upgrade behavior
type ValidationErrors ¶
type ValidationErrors []error
func (ValidationErrors) Error ¶
func (v ValidationErrors) Error() string
func (ValidationErrors) Return ¶
func (v ValidationErrors) Return() error