generator

package
v0.0.0-...-4dbb35b Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2025 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package generator provides functionality for parsing AsyncAPI specifications and generating corresponding Go type definitions.

The generator package offers both programmatic API access and CLI functionality for converting AsyncAPI event schemas into strongly-typed Go structs. It supports AsyncAPI versions 2.x and 3.x and generates idiomatic Go code with proper struct tags, comments, and naming conventions.

Basic Usage

The simplest way to use the generator is through the Generator struct:

config := &generator.Config{
	PackageName:     "events",
	OutputDir:       "./generated",
	IncludeComments: true,
	UsePointers:     true,
}

gen := generator.NewGenerator(config)

// Parse AsyncAPI specification
result, err := gen.Parse(asyncAPIData)
if err != nil {
	log.Fatal(err)
}

// Generate Go code
generated, err := gen.Generate(result.Messages)
if err != nil {
	log.Fatal(err)
}

Configuration Options

The Config struct provides several options for customizing code generation:

  • PackageName: The Go package name for generated files
  • OutputDir: Directory where generated files will be written
  • IncludeComments: Whether to include schema descriptions as Go comments
  • UsePointers: Whether to use pointer types for optional fields

File Operations

The generator supports reading AsyncAPI specifications from files and writing generated Go code to files:

// Parse from file and generate to files in one step
err := gen.ParseFileAndGenerateToFiles("api-spec.json")
if err != nil {
	log.Fatal(err)
}

// Or work with intermediate results
parseResult, err := gen.ParseFile("api-spec.json")
if err != nil {
	log.Fatal(err)
}

err = gen.GenerateToFiles(parseResult.Messages)
if err != nil {
	log.Fatal(err)
}

Supported AsyncAPI Features

The generator supports the following AsyncAPI/JSON Schema features:

  • Basic types: string, number, integer, boolean, array, object
  • String formats: date-time, date, time, email, uri, uuid, etc.
  • Numeric formats: int32, int64, float, double
  • Array types with typed elements
  • Nested object types (generates nested structs)
  • Required vs optional properties
  • Schema descriptions and titles
  • External schema references ($ref)

Type Mapping

AsyncAPI/JSON Schema types are mapped to Go types as follows:

  • string → string
  • number → float64
  • integer → int64
  • boolean → bool
  • array → []T (where T is the element type)
  • object → struct or any
  • string with date-time format → time.Time
  • string with email format → string
  • integer with int32 format → int32
  • number with float format → float32

Error Handling

The generator provides structured error types for different failure scenarios:

  • ParseError: Issues parsing AsyncAPI specifications
  • ValidationError: Schema validation failures
  • GenerationError: Code generation failures
  • UnsupportedVersionError: Unsupported AsyncAPI versions
  • FileError: File I/O operation failures
  • ResolverError: Schema reference resolution failures
  • CircularReferenceError: Circular schema reference detection

Examples

See the examples directory for complete usage examples:

  • examples/basic_usage: Basic programmatic usage
  • examples/file_operations: File I/O operations and advanced features

Thread Safety

Generator instances are not thread-safe. Create separate Generator instances for concurrent use, or use appropriate synchronization mechanisms.

Performance Considerations

For large AsyncAPI specifications:

  • The parser uses streaming for efficient memory usage
  • Schema references are cached to avoid redundant resolution
  • Generated code is formatted using go/format for optimal output

Validation

The generator performs validation at multiple levels:

  • AsyncAPI specification syntax and structure validation
  • Schema reference resolution and circular dependency detection
  • Generated Go code syntax validation and formatting
  • Configuration parameter validation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsFileError

func IsFileError(err error) bool

IsFileError checks if an error is a FileError

func IsValidGoIdentifier

func IsValidGoIdentifier(s string) bool

IsValidGoIdentifier checks if a string is a valid Go identifier

func ToJSONTag

func ToJSONTag(fieldName string) string

ToJSONTag creates a JSON tag for a field name

func ToPascalCase

func ToPascalCase(s string) string

ToPascalCase converts a string to PascalCase for Go naming conventions

Types

type AsyncAPIParser

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

AsyncAPIParser implements the Parser interface

func NewAsyncAPIParser

func NewAsyncAPIParser() *AsyncAPIParser

NewAsyncAPIParser creates a new AsyncAPI parser instance

func (*AsyncAPIParser) GetSupportedVersions

func (p *AsyncAPIParser) GetSupportedVersions() []string

GetSupportedVersions returns the list of supported AsyncAPI versions

func (*AsyncAPIParser) Parse

func (p *AsyncAPIParser) Parse(data []byte) (*ParseResult, error)

Parse parses AsyncAPI specification data and returns a ParseResult

func (*AsyncAPIParser) ValidateVersion

func (p *AsyncAPIParser) ValidateVersion(version string) error

ValidateVersion validates if the AsyncAPI version is supported

type AsyncAPISpec

type AsyncAPISpec struct {
	AsyncAPI     string                 `json:"asyncapi" yaml:"asyncapi"`
	ID           string                 `json:"id,omitempty" yaml:"id,omitempty"`
	Info         Info                   `json:"info" yaml:"info"`
	Servers      map[string]*Server     `json:"servers,omitempty" yaml:"servers,omitempty"`
	Channels     map[string]*Channel    `json:"channels,omitempty" yaml:"channels,omitempty"`
	Components   *Components            `json:"components,omitempty" yaml:"components,omitempty"`
	Tags         []*Tag                 `json:"tags,omitempty" yaml:"tags,omitempty"`
	ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
}

AsyncAPISpec represents a parsed AsyncAPI specification

type Channel

type Channel struct {
	Ref         string                `json:"$ref,omitempty" yaml:"$ref,omitempty"`
	Description string                `json:"description,omitempty" yaml:"description,omitempty"`
	Subscribe   *Operation            `json:"subscribe,omitempty" yaml:"subscribe,omitempty"`
	Publish     *Operation            `json:"publish,omitempty" yaml:"publish,omitempty"`
	Parameters  map[string]*Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
	Bindings    interface{}           `json:"bindings,omitempty" yaml:"bindings,omitempty"`
}

Channel represents an AsyncAPI channel

type CircularReferenceError

type CircularReferenceError struct {
	Reference string
	Stack     []string
}

CircularReferenceError represents circular reference errors

func (*CircularReferenceError) Error

func (e *CircularReferenceError) Error() string

type CodeGenerator

type CodeGenerator interface {
	GenerateTypes(messages map[string]*MessageSchema, config *Config) (*GenerateResult, error)
	GenerateStruct(schema *MessageSchema, name string) (string, error)
}

CodeGenerator transforms schemas into Go code

type Components

type Components struct {
	Schemas           map[string]*MessageSchema  `json:"schemas,omitempty" yaml:"schemas,omitempty"`
	Messages          map[string]*Message        `json:"messages,omitempty" yaml:"messages,omitempty"`
	SecuritySchemes   map[string]*SecurityScheme `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
	Parameters        map[string]*Parameter      `json:"parameters,omitempty" yaml:"parameters,omitempty"`
	CorrelationIDs    map[string]*CorrelationID  `json:"correlationIds,omitempty" yaml:"correlationIds,omitempty"`
	OperationTraits   map[string]*OperationTrait `json:"operationTraits,omitempty" yaml:"operationTraits,omitempty"`
	MessageTraits     map[string]*MessageTrait   `json:"messageTraits,omitempty" yaml:"messageTraits,omitempty"`
	ServerBindings    map[string]interface{}     `json:"serverBindings,omitempty" yaml:"serverBindings,omitempty"`
	ChannelBindings   map[string]interface{}     `json:"channelBindings,omitempty" yaml:"channelBindings,omitempty"`
	OperationBindings map[string]interface{}     `json:"operationBindings,omitempty" yaml:"operationBindings,omitempty"`
	MessageBindings   map[string]interface{}     `json:"messageBindings,omitempty" yaml:"messageBindings,omitempty"`
}

Components represents AsyncAPI components section

type Config

type Config struct {
	PackageName     string
	OutputDir       string
	IncludeComments bool
	UsePointers     bool
}

Config holds generation configuration options

type Contact

type Contact struct {
	Name  string `json:"name,omitempty" yaml:"name,omitempty"`
	URL   string `json:"url,omitempty" yaml:"url,omitempty"`
	Email string `json:"email,omitempty" yaml:"email,omitempty"`
}

Contact represents contact information

type CorrelationID

type CorrelationID struct {
	Description string `json:"description,omitempty" yaml:"description,omitempty"`
	Location    string `json:"location" yaml:"location"`
}

CorrelationID represents a correlation ID

type DefaultCodeGenerator

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

DefaultCodeGenerator implements the CodeGenerator interface

func NewCodeGenerator

func NewCodeGenerator(config *Config) *DefaultCodeGenerator

NewCodeGenerator creates a new DefaultCodeGenerator instance

func (*DefaultCodeGenerator) GenerateStruct

func (cg *DefaultCodeGenerator) GenerateStruct(schema *MessageSchema, name string) (string, error)

GenerateStruct generates a Go struct from a message schema

func (*DefaultCodeGenerator) GenerateTypes

func (cg *DefaultCodeGenerator) GenerateTypes(messages map[string]*MessageSchema, config *Config) (*GenerateResult, error)

GenerateTypes generates Go type definitions from message schemas

type DefaultFileManager

type DefaultFileManager struct{}

DefaultFileManager implements the FileManager interface

func NewFileManager

func NewFileManager() *DefaultFileManager

NewFileManager creates a new DefaultFileManager instance

func (*DefaultFileManager) CreateDir

func (fm *DefaultFileManager) CreateDir(path string) error

CreateDir creates a directory and all necessary parent directories

func (*DefaultFileManager) IsAsyncAPIFile

func (fm *DefaultFileManager) IsAsyncAPIFile(path string) bool

IsAsyncAPIFile checks if the file has a valid AsyncAPI file extension

func (*DefaultFileManager) ReadFile

func (fm *DefaultFileManager) ReadFile(path string) ([]byte, error)

ReadFile reads a file from the specified path and returns its contents

func (*DefaultFileManager) ValidatePath

func (fm *DefaultFileManager) ValidatePath(path string) error

ValidatePath validates a file or directory path

func (*DefaultFileManager) WriteFile

func (fm *DefaultFileManager) WriteFile(path string, content []byte) error

WriteFile writes content to the specified file path

type DefaultSchemaResolver

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

DefaultSchemaResolver implements the SchemaResolver interface

func NewSchemaResolver

func NewSchemaResolver(baseURI string) *DefaultSchemaResolver

NewSchemaResolver creates a new schema resolver instance

func (*DefaultSchemaResolver) ClearCache

func (r *DefaultSchemaResolver) ClearCache()

ClearCache clears the resolver's cache

func (*DefaultSchemaResolver) GetCacheSize

func (r *DefaultSchemaResolver) GetCacheSize() int

GetCacheSize returns the number of cached items

func (*DefaultSchemaResolver) ResolveProperty

func (r *DefaultSchemaResolver) ResolveProperty(ref string) (*Property, error)

ResolveProperty resolves a $ref to a Property

func (*DefaultSchemaResolver) ResolveRef

func (r *DefaultSchemaResolver) ResolveRef(ref string) (*MessageSchema, error)

ResolveRef resolves a $ref to a MessageSchema

func (*DefaultSchemaResolver) SetBaseURI

func (r *DefaultSchemaResolver) SetBaseURI(baseURI string)

SetBaseURI sets the base URI for resolving relative references

type DefaultTypeMapper

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

DefaultTypeMapper implements the TypeMapper interface

func NewTypeMapper

func NewTypeMapper(config *Config) *DefaultTypeMapper

NewTypeMapper creates a new DefaultTypeMapper instance

func (*DefaultTypeMapper) MapProperty

func (tm *DefaultTypeMapper) MapProperty(prop *Property) *GoField

MapProperty maps a Property to a GoField

func (*DefaultTypeMapper) MapPropertyWithContext

func (tm *DefaultTypeMapper) MapPropertyWithContext(prop *Property, fieldName string, required bool) *GoField

MapPropertyWithContext maps a property with additional context about whether it's required

func (*DefaultTypeMapper) MapType

func (tm *DefaultTypeMapper) MapType(schemaType string, format string) string

MapType maps AsyncAPI/JSON Schema types to Go types

type EnumInfo

type EnumInfo struct {
	TypeName string
	Values   []interface{}
	BaseType string
}

EnumInfo contains information about an enum type

type EnumType

type EnumType struct {
	Name     string
	BaseType string
	Values   []EnumValue
	Comment  string
}

EnumType represents a Go enum type definition

type EnumValue

type EnumValue struct {
	Name    string
	Value   interface{}
	Comment string
}

EnumValue represents a single enum value

type EventBridgeEvent

type EventBridgeEvent struct {
	Version    string                 `json:"version"`
	ID         string                 `json:"id"`
	DetailType string                 `json:"detail-type"`
	Source     string                 `json:"source"`
	Account    string                 `json:"account"`
	Time       time.Time              `json:"time"`
	Region     string                 `json:"region"`
	Detail     map[string]interface{} `json:"detail"`
	Resources  []string               `json:"resources,omitempty"`
}

EventBridgeEvent represents the structure of an AWS EventBridge event

type EventBridgeValidator

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

EventBridgeValidator provides specialized validation functionality for AWS EventBridge events. It validates both the EventBridge event structure (version, id, detail-type, source, etc.) and the event detail payload against AsyncAPI schemas.

EventBridge events have a specific structure that must be followed:

  • version: Must be "0"
  • id: Unique event identifier
  • detail-type: Descriptive event type
  • source: Event source in reverse DNS notation
  • account: 12-digit AWS account ID
  • time: ISO 8601 timestamp
  • region: Valid AWS region
  • detail: Event payload object

Example usage:

validator := NewEventBridgeValidator()

// Validate EventBridge event structure
result := validator.ValidateEventBridgeEvent(eventJSON)

// Validate with detail schema
result = validator.ValidateEventBridgeEventWithSchema(eventJSON, detailSchema)

func NewEventBridgeValidator

func NewEventBridgeValidator() *EventBridgeValidator

NewEventBridgeValidator creates a new EventBridgeValidator instance. The validator uses a permissive base validator for detail payload validation, allowing additional properties in the detail object.

Returns:

  • A new EventBridgeValidator instance ready for validating EventBridge events

Example:

validator := NewEventBridgeValidator()
result := validator.ValidateEventBridgeEvent(eventJSON)

func (*EventBridgeValidator) ValidateEventBridgeEvent

func (v *EventBridgeValidator) ValidateEventBridgeEvent(eventData []byte) *ValidationResult

ValidateEventBridgeEvent validates the structure and format of an AWS EventBridge event. This method validates the required EventBridge fields and their formats, but does not validate the detail payload against a specific schema.

Parameters:

  • eventData: Raw JSON data representing the EventBridge event

Returns:

  • ValidationResult indicating whether the event structure is valid

The method validates:

  • Required fields: version, id, detail-type, source, account, time, region, detail
  • Field formats: version should be "0", account should be 12-digit number, etc.
  • Source format: should follow reverse DNS notation
  • Region format: should be a valid AWS region format

Example:

eventJSON := []byte(`{
    "version": "0",
    "id": "12345678-1234-1234-1234-123456789012",
    "detail-type": "User Signup",
    "source": "com.example.userservice",
    "account": "123456789012",
    "time": "2023-01-01T12:00:00Z",
    "region": "us-east-1",
    "detail": {"userId": "user123"}
}`)
result := validator.ValidateEventBridgeEvent(eventJSON)

func (*EventBridgeValidator) ValidateEventBridgeEventWithSchema

func (v *EventBridgeValidator) ValidateEventBridgeEventWithSchema(eventData []byte, detailSchema *MessageSchema) *ValidationResult

ValidateEventBridgeEventWithSchema validates both the EventBridge event structure and the detail payload against a provided AsyncAPI schema.

Parameters:

  • eventData: Raw JSON data representing the EventBridge event
  • detailSchema: AsyncAPI MessageSchema to validate the detail payload against

Returns:

  • ValidationResult indicating whether both the event structure and detail payload are valid

This method first validates the EventBridge event structure using ValidateEventBridgeEvent, then validates the detail payload against the provided schema. All validation errors from both validations are included in the result.

Example:

detailSchema := &MessageSchema{
    Type: "object",
    Properties: map[string]*Property{
        "userId": {Type: "string"},
        "email":  {Type: "string"},
    },
    Required: []string{"userId", "email"},
}
result := validator.ValidateEventBridgeEventWithSchema(eventJSON, detailSchema)

func (*EventBridgeValidator) ValidateEventPattern

func (v *EventBridgeValidator) ValidateEventPattern(patternData []byte) *ValidationResult

ValidateEventPattern validates an EventBridge event pattern

type ExternalDocumentation

type ExternalDocumentation struct {
	Description string `json:"description,omitempty" yaml:"description,omitempty"`
	URL         string `json:"url" yaml:"url"`
}

ExternalDocumentation represents external documentation

type FileError

type FileError struct {
	Operation string
	Path      string
	Message   string
}

FileError represents file operation errors

func GetFileError

func GetFileError(err error) *FileError

GetFileError extracts FileError from an error, returns nil if not a FileError

func (*FileError) Error

func (e *FileError) Error() string

type FileManager

type FileManager interface {
	ReadFile(path string) ([]byte, error)
	WriteFile(path string, content []byte) error
	CreateDir(path string) error
}

FileManager handles file I/O operations

type GenerateResult

type GenerateResult struct {
	Files  map[string]string // filename -> content
	Errors []error
}

GenerateResult contains the generated Go code

type GenerationError

type GenerationError struct {
	Schema  string
	Message string
}

GenerationError represents code generation errors

func (*GenerationError) Error

func (e *GenerationError) Error() string

type Generator

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

Generator provides the main API for AsyncAPI to Go code generation

func NewGenerator

func NewGenerator(config *Config) *Generator

NewGenerator creates a new Generator instance with the provided configuration

func (*Generator) Generate

func (g *Generator) Generate(messages map[string]*MessageSchema) (*GenerateResult, error)

Generate generates Go code from parsed AsyncAPI messages

func (*Generator) GenerateToFiles

func (g *Generator) GenerateToFiles(messages map[string]*MessageSchema) error

GenerateToFiles generates Go code and writes it to files in the output directory

func (*Generator) GetConfig

func (g *Generator) GetConfig() *Config

GetConfig returns the current configuration

func (*Generator) GetSupportedVersions

func (g *Generator) GetSupportedVersions() []string

GetSupportedVersions returns the AsyncAPI versions supported by the parser

func (*Generator) Parse

func (g *Generator) Parse(data []byte) (*ParseResult, error)

Parse parses an AsyncAPI specification from raw data

func (*Generator) ParseAndGenerate

func (g *Generator) ParseAndGenerate(data []byte) (*GenerateResult, error)

ParseAndGenerate is a convenience method that parses and generates in one call

func (*Generator) ParseAndGenerateToFiles

func (g *Generator) ParseAndGenerateToFiles(data []byte) error

ParseAndGenerateToFiles is a convenience method that parses and generates files in one call

func (*Generator) ParseFile

func (g *Generator) ParseFile(filePath string) (*ParseResult, error)

ParseFile parses an AsyncAPI specification from a file path

func (*Generator) ParseFileAndGenerateToFiles

func (g *Generator) ParseFileAndGenerateToFiles(filePath string) error

ParseFileAndGenerateToFiles parses a file and generates output files

func (*Generator) SetConfig

func (g *Generator) SetConfig(config *Config)

SetConfig updates the generator configuration

func (*Generator) ValidateConfig

func (g *Generator) ValidateConfig() error

ValidateConfig validates the generator configuration

type GoField

type GoField struct {
	Name          string
	Type          string
	JSONTag       string
	Comment       string
	Optional      bool
	IsEnum        bool
	EnumValues    []interface{}
	EnumBaseType  string
	ArrayItemEnum *EnumInfo // For arrays of enums
}

GoField represents a Go struct field

type GoStruct

type GoStruct struct {
	Name        string
	PackageName string
	Fields      []*GoField
	Comments    []string
}

GoStruct represents a generated Go struct

type Info

type Info struct {
	Title          string   `json:"title" yaml:"title"`
	Version        string   `json:"version" yaml:"version"`
	Description    string   `json:"description,omitempty" yaml:"description,omitempty"`
	TermsOfService string   `json:"termsOfService,omitempty" yaml:"termsOfService,omitempty"`
	Contact        *Contact `json:"contact,omitempty" yaml:"contact,omitempty"`
	License        *License `json:"license,omitempty" yaml:"license,omitempty"`
}

Info represents AsyncAPI info section

type License

type License struct {
	Name string `json:"name" yaml:"name"`
	URL  string `json:"url,omitempty" yaml:"url,omitempty"`
}

License represents license information

type Message

type Message struct {
	Ref           string                   `json:"$ref,omitempty" yaml:"$ref,omitempty"`
	Headers       *MessageSchema           `json:"headers,omitempty" yaml:"headers,omitempty"`
	Payload       *MessageSchema           `json:"payload,omitempty" yaml:"payload,omitempty"`
	CorrelationID *CorrelationID           `json:"correlationId,omitempty" yaml:"correlationId,omitempty"`
	SchemaFormat  string                   `json:"schemaFormat,omitempty" yaml:"schemaFormat,omitempty"`
	ContentType   string                   `json:"contentType,omitempty" yaml:"contentType,omitempty"`
	Name          string                   `json:"name,omitempty" yaml:"name,omitempty"`
	Title         string                   `json:"title,omitempty" yaml:"title,omitempty"`
	Summary       string                   `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description   string                   `json:"description,omitempty" yaml:"description,omitempty"`
	Tags          []*Tag                   `json:"tags,omitempty" yaml:"tags,omitempty"`
	ExternalDocs  *ExternalDocumentation   `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
	Bindings      interface{}              `json:"bindings,omitempty" yaml:"bindings,omitempty"`
	Examples      []map[string]interface{} `json:"examples,omitempty" yaml:"examples,omitempty"`
	Traits        []*MessageTrait          `json:"traits,omitempty" yaml:"traits,omitempty"`
}

Message represents an AsyncAPI message

type MessageSchema

type MessageSchema struct {
	// Schema identification
	Ref    string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
	ID     string `json:"$id,omitempty" yaml:"$id,omitempty"`
	Schema string `json:"$schema,omitempty" yaml:"$schema,omitempty"`

	// Basic schema properties
	Title       string        `json:"title,omitempty" yaml:"title,omitempty"`
	Description string        `json:"description,omitempty" yaml:"description,omitempty"`
	Default     interface{}   `json:"default,omitempty" yaml:"default,omitempty"`
	Examples    []interface{} `json:"examples,omitempty" yaml:"examples,omitempty"`

	// Type and validation
	Type  string        `json:"type,omitempty" yaml:"type,omitempty"`
	Enum  []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
	Const interface{}   `json:"const,omitempty" yaml:"const,omitempty"`

	// Numeric validation
	MultipleOf       *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
	Maximum          *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
	ExclusiveMaximum *float64 `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
	Minimum          *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
	ExclusiveMinimum *float64 `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`

	// String validation
	MaxLength *int   `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
	MinLength *int   `json:"minLength,omitempty" yaml:"minLength,omitempty"`
	Pattern   string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
	Format    string `json:"format,omitempty" yaml:"format,omitempty"`

	// Array validation
	Items           *Property `json:"items,omitempty" yaml:"items,omitempty"`
	AdditionalItems *Property `json:"additionalItems,omitempty" yaml:"additionalItems,omitempty"`
	MaxItems        *int      `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
	MinItems        *int      `json:"minItems,omitempty" yaml:"minItems,omitempty"`
	UniqueItems     *bool     `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`

	// Object validation
	Properties           map[string]*Property `json:"properties,omitempty" yaml:"properties,omitempty"`
	PatternProperties    map[string]*Property `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
	AdditionalProperties interface{}          `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
	Required             []string             `json:"required,omitempty" yaml:"required,omitempty"`
	PropertyNames        *Property            `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
	MaxProperties        *int                 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
	MinProperties        *int                 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`

	// Composition
	AllOf []*Property `json:"allOf,omitempty" yaml:"allOf,omitempty"`
	AnyOf []*Property `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
	OneOf []*Property `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
	Not   *Property   `json:"not,omitempty" yaml:"not,omitempty"`

	// Conditional
	If   *Property `json:"if,omitempty" yaml:"if,omitempty"`
	Then *Property `json:"then,omitempty" yaml:"then,omitempty"`
	Else *Property `json:"else,omitempty" yaml:"else,omitempty"`

	// Annotations
	ReadOnly  *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`
	WriteOnly *bool `json:"writeOnly,omitempty" yaml:"writeOnly,omitempty"`

	// Non-standard fields for internal use
	Name string `json:"-" yaml:"-"` // Used internally for struct naming
}

MessageSchema represents an AsyncAPI message schema

func CreateEventBridgeEventSchema

func CreateEventBridgeEventSchema() *MessageSchema

CreateEventBridgeEventSchema creates a schema for validating EventBridge events

type MessageTrait

type MessageTrait struct {
	Headers       *MessageSchema           `json:"headers,omitempty" yaml:"headers,omitempty"`
	CorrelationID *CorrelationID           `json:"correlationId,omitempty" yaml:"correlationId,omitempty"`
	SchemaFormat  string                   `json:"schemaFormat,omitempty" yaml:"schemaFormat,omitempty"`
	ContentType   string                   `json:"contentType,omitempty" yaml:"contentType,omitempty"`
	Name          string                   `json:"name,omitempty" yaml:"name,omitempty"`
	Title         string                   `json:"title,omitempty" yaml:"title,omitempty"`
	Summary       string                   `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description   string                   `json:"description,omitempty" yaml:"description,omitempty"`
	Tags          []*Tag                   `json:"tags,omitempty" yaml:"tags,omitempty"`
	ExternalDocs  *ExternalDocumentation   `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
	Bindings      interface{}              `json:"bindings,omitempty" yaml:"bindings,omitempty"`
	Examples      []map[string]interface{} `json:"examples,omitempty" yaml:"examples,omitempty"`
}

MessageTrait represents a message trait

type OAuthFlow

type OAuthFlow struct {
	AuthorizationURL string            `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
	TokenURL         string            `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
	RefreshURL       string            `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
	Scopes           map[string]string `json:"scopes" yaml:"scopes"`
}

OAuthFlow represents an OAuth flow

type OAuthFlows

type OAuthFlows struct {
	Implicit          *OAuthFlow `json:"implicit,omitempty" yaml:"implicit,omitempty"`
	Password          *OAuthFlow `json:"password,omitempty" yaml:"password,omitempty"`
	ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty" yaml:"clientCredentials,omitempty"`
	AuthorizationCode *OAuthFlow `json:"authorizationCode,omitempty" yaml:"authorizationCode,omitempty"`
}

OAuthFlows represents OAuth flows

type Operation

type Operation struct {
	OperationID  string                 `json:"operationId,omitempty" yaml:"operationId,omitempty"`
	Summary      string                 `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description  string                 `json:"description,omitempty" yaml:"description,omitempty"`
	Security     []map[string][]string  `json:"security,omitempty" yaml:"security,omitempty"`
	Tags         []*Tag                 `json:"tags,omitempty" yaml:"tags,omitempty"`
	ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
	Bindings     interface{}            `json:"bindings,omitempty" yaml:"bindings,omitempty"`
	Traits       []*OperationTrait      `json:"traits,omitempty" yaml:"traits,omitempty"`
	Message      *Message               `json:"message,omitempty" yaml:"message,omitempty"`
}

Operation represents a channel operation

type OperationTrait

type OperationTrait struct {
	OperationID  string                 `json:"operationId,omitempty" yaml:"operationId,omitempty"`
	Summary      string                 `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description  string                 `json:"description,omitempty" yaml:"description,omitempty"`
	Tags         []*Tag                 `json:"tags,omitempty" yaml:"tags,omitempty"`
	ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
	Bindings     interface{}            `json:"bindings,omitempty" yaml:"bindings,omitempty"`
}

OperationTrait represents an operation trait

type Parameter

type Parameter struct {
	Description string    `json:"description,omitempty" yaml:"description,omitempty"`
	Schema      *Property `json:"schema,omitempty" yaml:"schema,omitempty"`
}

Parameter represents a channel parameter

type ParseError

type ParseError struct {
	Message string
	Line    int
	Column  int
}

ParseError represents AsyncAPI parsing errors

func (*ParseError) Error

func (e *ParseError) Error() string

type ParseResult

type ParseResult struct {
	Spec     *AsyncAPISpec
	Messages map[string]*MessageSchema
	Errors   []error
}

ParseResult contains the parsed AsyncAPI specification

type Parser

type Parser interface {
	Parse(data []byte) (*ParseResult, error)
	ValidateVersion(version string) error
}

Parser handles AsyncAPI specification parsing

type Property

type Property struct {
	// Schema identification
	Ref    string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
	ID     string `json:"$id,omitempty" yaml:"$id,omitempty"`
	Schema string `json:"$schema,omitempty" yaml:"$schema,omitempty"`

	// Basic schema properties
	Title       string        `json:"title,omitempty" yaml:"title,omitempty"`
	Description string        `json:"description,omitempty" yaml:"description,omitempty"`
	Default     interface{}   `json:"default,omitempty" yaml:"default,omitempty"`
	Examples    []interface{} `json:"examples,omitempty" yaml:"examples,omitempty"`

	// Type and validation
	Type  string        `json:"type,omitempty" yaml:"type,omitempty"`
	Enum  []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
	Const interface{}   `json:"const,omitempty" yaml:"const,omitempty"`

	// Numeric validation
	MultipleOf       *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
	Maximum          *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
	ExclusiveMaximum *float64 `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
	Minimum          *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
	ExclusiveMinimum *float64 `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`

	// String validation
	MaxLength *int   `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
	MinLength *int   `json:"minLength,omitempty" yaml:"minLength,omitempty"`
	Pattern   string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
	Format    string `json:"format,omitempty" yaml:"format,omitempty"`

	// Array validation
	Items           *Property `json:"items,omitempty" yaml:"items,omitempty"`
	AdditionalItems *Property `json:"additionalItems,omitempty" yaml:"additionalItems,omitempty"`
	MaxItems        *int      `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
	MinItems        *int      `json:"minItems,omitempty" yaml:"minItems,omitempty"`
	UniqueItems     *bool     `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`

	// Object validation
	Properties           map[string]*Property `json:"properties,omitempty" yaml:"properties,omitempty"`
	PatternProperties    map[string]*Property `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
	AdditionalProperties interface{}          `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
	Required             []string             `json:"required,omitempty" yaml:"required,omitempty"`
	PropertyNames        *Property            `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
	MaxProperties        *int                 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
	MinProperties        *int                 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`

	// Composition
	AllOf []*Property `json:"allOf,omitempty" yaml:"allOf,omitempty"`
	AnyOf []*Property `json:"anyOf,omitempty" yaml:"anyOf,omitempty"`
	OneOf []*Property `json:"oneOf,omitempty" yaml:"oneOf,omitempty"`
	Not   *Property   `json:"not,omitempty" yaml:"not,omitempty"`

	// Conditional
	If   *Property `json:"if,omitempty" yaml:"if,omitempty"`
	Then *Property `json:"then,omitempty" yaml:"then,omitempty"`
	Else *Property `json:"else,omitempty" yaml:"else,omitempty"`

	// Annotations
	ReadOnly  *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`
	WriteOnly *bool `json:"writeOnly,omitempty" yaml:"writeOnly,omitempty"`
}

Property represents a schema property (same structure as MessageSchema for JSON Schema compatibility)

type ResolverError

type ResolverError struct {
	Reference string
	Message   string
}

ResolverError represents schema resolution errors

func (*ResolverError) Error

func (e *ResolverError) Error() string

type SchemaResolver

type SchemaResolver interface {
	ResolveRef(ref string) (*MessageSchema, error)
	ResolveProperty(ref string) (*Property, error)
}

SchemaResolver handles external schema references

type SchemaValidator

type SchemaValidator struct {
	// StrictMode determines whether additional properties are allowed.
	// When true, the validator will reject any properties not defined in the schema.
	// When false, additional properties are allowed (permissive mode).
	StrictMode bool
}

SchemaValidator implements the Validator interface and provides JSON schema validation capabilities for AsyncAPI schemas. It validates data against AsyncAPI/JSON Schema constraints including type validation, constraint validation, enum validation, and required field validation.

The validator supports two modes:

  • Strict mode: Rejects additional properties not defined in the schema
  • Permissive mode: Allows additional properties (default behavior)

Example usage:

// Create a permissive validator (allows extra properties)
validator := NewValidator(false)

// Create a strict validator (rejects extra properties)
strictValidator := NewValidator(true)

// Validate JSON data
result := validator.ValidateJSON(jsonData, schema)
if !result.Valid {
    for _, err := range result.Errors {
        fmt.Printf("Field '%s': %s\n", err.Field, err.Message)
    }
}

func (*SchemaValidator) ValidateJSON

func (v *SchemaValidator) ValidateJSON(jsonData []byte, schema *MessageSchema) *ValidationResult

ValidateJSON validates raw JSON data against a MessageSchema. This method first parses the JSON data and then validates it against the provided schema. It handles JSON parsing errors as well as schema validation errors.

Parameters:

  • jsonData: Raw JSON data as bytes to be validated
  • schema: The MessageSchema to validate against

Returns:

  • ValidationResult containing validation status and any errors found

The method performs the following validations:

  • JSON syntax validation (parsing)
  • Type validation (string, number, boolean, array, object)
  • Constraint validation (min/max length, numeric ranges, patterns)
  • Enum validation
  • Required field validation
  • Additional property validation (based on StrictMode)

Example:

jsonData := []byte(`{"name": "John", "age": 30}`)
result := validator.ValidateJSON(jsonData, schema)
if !result.Valid {
    for _, err := range result.Errors {
        fmt.Printf("Error in %s: %s\n", err.Field, err.Message)
    }
}

func (*SchemaValidator) ValidateMessage

func (v *SchemaValidator) ValidateMessage(data any, message *MessageSchema) *ValidationResult

ValidateMessage validates a message payload against its MessageSchema. The data should be a Go value (typically map[string]any from JSON unmarshaling) that represents the message payload.

Parameters:

  • data: The data to validate (typically map[string]any, but can be any Go type)
  • message: The MessageSchema to validate against

Returns:

  • ValidationResult containing validation status and any errors found

This method is useful when you already have parsed data (e.g., from JSON unmarshaling) and want to validate it against a schema without re-parsing JSON.

Example:

var data map[string]any
json.Unmarshal(jsonBytes, &data)
result := validator.ValidateMessage(data, schema)

func (*SchemaValidator) ValidateValue

func (v *SchemaValidator) ValidateValue(value any, schema *Property, fieldPath string) *ValidationResult

ValidateValue validates a Go value against a Property schema. This is the core validation method that performs detailed validation of individual values against their schema constraints.

Parameters:

  • value: The value to validate (can be any Go type)
  • schema: The Property schema defining validation rules
  • fieldPath: The path to this field for error reporting (e.g., "user.profile.age")

Returns:

  • ValidationResult containing validation status and any errors found

The method validates:

  • Type correctness (string, number, boolean, array, object)
  • String constraints (minLength, maxLength, pattern)
  • Numeric constraints (minimum, maximum, multipleOf)
  • Array constraints (minItems, maxItems, uniqueItems)
  • Object constraints (required properties, additional properties)
  • Enum constraints
  • Const constraints

Example:

schema := &Property{Type: "string", MinLength: &[]int{3}[0]}
result := validator.ValidateValue("hi", schema, "name")
// result.Valid will be false because "hi" is shorter than 3 characters

type SecurityScheme

type SecurityScheme struct {
	Type             string      `json:"type" yaml:"type"`
	Description      string      `json:"description,omitempty" yaml:"description,omitempty"`
	Name             string      `json:"name,omitempty" yaml:"name,omitempty"`
	In               string      `json:"in,omitempty" yaml:"in,omitempty"`
	Scheme           string      `json:"scheme,omitempty" yaml:"scheme,omitempty"`
	BearerFormat     string      `json:"bearerFormat,omitempty" yaml:"bearerFormat,omitempty"`
	Flows            *OAuthFlows `json:"flows,omitempty" yaml:"flows,omitempty"`
	OpenIDConnectURL string      `json:"openIdConnectUrl,omitempty" yaml:"openIdConnectUrl,omitempty"`
}

SecurityScheme represents a security scheme

type Server

type Server struct {
	URL         string                `json:"url" yaml:"url"`
	Protocol    string                `json:"protocol" yaml:"protocol"`
	Description string                `json:"description,omitempty" yaml:"description,omitempty"`
	Variables   map[string]*Variable  `json:"variables,omitempty" yaml:"variables,omitempty"`
	Security    []map[string][]string `json:"security,omitempty" yaml:"security,omitempty"`
	Tags        []*Tag                `json:"tags,omitempty" yaml:"tags,omitempty"`
}

Server represents an AsyncAPI server

type Tag

type Tag struct {
	Name         string                 `json:"name" yaml:"name"`
	Description  string                 `json:"description,omitempty" yaml:"description,omitempty"`
	ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
}

Tag represents a tag

type TypeMapper

type TypeMapper interface {
	MapType(schemaType string, format string) string
	MapProperty(prop *Property) *GoField
	MapPropertyWithContext(prop *Property, fieldName string, required bool) *GoField
}

TypeMapper maps AsyncAPI types to Go types

type UnsupportedVersionError

type UnsupportedVersionError struct {
	Version           string
	SupportedVersions []string
}

UnsupportedVersionError represents unsupported AsyncAPI version errors

func (*UnsupportedVersionError) Error

func (e *UnsupportedVersionError) Error() string

type ValidationError

type ValidationError struct {
	// Field is the path to the field that failed validation (e.g., "user.profile.age").
	// An empty field indicates a root-level validation error.
	Field string

	// Message is a human-readable description of the validation error.
	Message string
}

ValidationError represents a single schema validation error with field path and message. It provides detailed information about what validation rule was violated and where in the data structure the error occurred.

ValidationError implements the error interface and can be used as a standard Go error.

Example:

err := &ValidationError{
    Field:   "user.profile.age",
    Message: "value 200 exceeds maximum 150",
}
fmt.Println(err.Error()) // "validation error in field 'user.profile.age': value 200 exceeds maximum 150"

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error implements the error interface for ValidationError. It returns a formatted error message that includes the field path (if available) and the validation message.

type ValidationErrorWithValue

type ValidationErrorWithValue struct {
	*ValidationError
	// Value is the actual value that failed validation
	Value any `json:"value,omitempty"`
}

ValidationErrorWithValue extends ValidationError with the actual value that failed validation. This is useful for debugging and providing more context in error messages.

type ValidationResult

type ValidationResult struct {
	// Valid indicates whether the validation passed (true) or failed (false)
	Valid bool `json:"valid"`

	// Errors contains all validation errors found during validation.
	// This slice is empty when Valid is true.
	Errors []*ValidationError `json:"errors,omitempty"`
}

ValidationResult contains the complete result of a validation operation. It includes the validation status and any errors that were encountered.

Example usage:

result := validator.ValidateJSON(jsonData, schema)
if !result.Valid {
    for _, err := range result.Errors {
        fmt.Printf("Validation error in field '%s': %s\n", err.Field, err.Message)
    }
}

func (*ValidationResult) AddError

func (r *ValidationResult) AddError(field, message string, value any)

AddError adds a validation error to the result

type Validator

type Validator interface {
	// ValidateValue validates a Go value against a Property schema.
	// The value can be any Go type (string, int, map[string]any, []any, etc.).
	// The schema defines the expected structure and constraints.
	// The fieldPath is used for error reporting and should represent the path
	// to the field being validated (e.g., "user.profile.age").
	//
	// Returns a ValidationResult containing validation status and any errors.
	ValidateValue(value any, schema *Property, fieldPath string) *ValidationResult

	// ValidateJSON validates raw JSON data against a MessageSchema.
	// The JSON data is first parsed and then validated against the schema.
	// This method handles JSON parsing errors as well as schema validation errors.
	//
	// Returns a ValidationResult containing validation status and any errors.
	// If the JSON is malformed, the result will contain a parsing error.
	ValidateJSON(jsonData []byte, schema *MessageSchema) *ValidationResult

	// ValidateMessage validates a message payload against its MessageSchema.
	// The data should be a Go value (typically map[string]any from JSON unmarshaling)
	// that represents the message payload.
	//
	// Returns a ValidationResult containing validation status and any errors.
	ValidateMessage(data any, message *MessageSchema) *ValidationResult
}

Validator provides JSON schema validation capabilities for AsyncAPI schemas. It validates data against AsyncAPI/JSON Schema constraints including type validation, constraint validation (min/max length, numeric ranges, patterns), enum validation, and required field validation.

Example usage:

validator := NewValidator(false) // permissive mode
result := validator.ValidateJSON(jsonData, schema)
if !result.Valid {
    for _, err := range result.Errors {
        fmt.Printf("Field '%s': %s\n", err.Field, err.Message)
    }
}

func NewValidator

func NewValidator(strictMode bool) Validator

NewValidator creates a new SchemaValidator instance with the specified strict mode setting.

Parameters:

  • strictMode: If true, the validator will reject additional properties not defined in the schema. If false, additional properties are allowed (permissive mode).

Returns:

  • A Validator interface implementation that can be used to validate data against AsyncAPI schemas.

Example:

// Create a permissive validator
validator := NewValidator(false)

// Create a strict validator
strictValidator := NewValidator(true)

type Variable

type Variable struct {
	Enum        []string `json:"enum,omitempty" yaml:"enum,omitempty"`
	Default     string   `json:"default,omitempty" yaml:"default,omitempty"`
	Description string   `json:"description,omitempty" yaml:"description,omitempty"`
	Examples    []string `json:"examples,omitempty" yaml:"examples,omitempty"`
}

Variable represents a server variable

Jump to

Keyboard shortcuts

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