Documentation
¶
Overview ¶
Package golang generates Go model types from OpenAPI schemas and generates OpenAPI schemas from Go runtime types.
The package is intentionally library-only. It does not provide a CLI, generated client or server code, a validation runtime, or runtime helper package. Callers provide libopenapi schema models or Go reflection types and receive generated Go source or OpenAPI schema proxies.
OpenAPI to Go model generation starts with RenderSchema for a single schema or Generator.RenderSchemas for component maps. The generated source is gofmt-formatted and diagnostics report schema shapes that do not map directly to plain Go model fields.
Go to OpenAPI generation starts with SchemaFromType for a single schema or Generator.SchemasFromTypes for a reusable component graph. Package-level graph helpers also have WithOptions variants for callers that do not need to keep a Generator instance. Named reflected structs, enums, and registered interface unions are emitted as components, nested named model references are rendered as component $refs, and SchemaSet.Roots exposes every requested root. WithTypeSchema maps reflected project scalar aliases to explicit OpenAPI schema models without adding methods to the scalar type, and WithFieldSchema/WithFieldSchemaByJSONName map individual struct fields to exact schema models while keeping the surrounding type reflected normally. Reflected nullable values use JSON Schema 2020-12 native nullability rather than OpenAPI 3.0 nullable: direct schemas use type arrays that include "null", and nullable component references use anyOf wrappers.
Reflection metadata is layered. Field-level openapi struct tags handle compact scalar metadata such as format, constraints, enum, const, readOnly/writeOnly/deprecated, and nullable overrides. SchemaProvider, SchemaMetadataProvider, and SchemaYAMLProvider methods handle exact type-level schemas. OpenAPI-to-Go generation can opt into WithOpenAPITags and WithSchemaMetadataSidecar to emit those hooks into a separate schema_metadata.go source file for higher-fidelity Go-to-OpenAPI round trips. Disabling the metadata sidecar leaves GeneratedFile.SchemaMetadata nil and keeps generated code leaner, but recreating the original OpenAPI input from reflected Go types becomes intentionally lossy.
Polymorphic oneOf schemas with an explicit discriminator, or an inferable required const discriminator, render as typed union wrappers. Ambiguous oneOf and anyOf schemas render as json.RawMessage wrappers so the generated model remains dependency-free and does not embed validation behavior.
Schema-valued additionalProperties can round-trip unknown JSON object fields through generated marshal/unmarshal methods. WithAdditionalPropertiesMethods disables those methods when callers want to provide JSON behavior themselves.
Inline schema type names use "_" as the default parent/child delimiter. WithNestedTypeNameDelimiter changes that delimiter, including to an empty string for compact names. Name collisions use "__" before the numeric suffix. Component names are collision-resolved before local refs are rendered, so generated fields point at the final Go type names.
Index ¶
- Constants
- Variables
- func RenderSchema(name string, schema *highbase.SchemaProxy, opts ...Option) ([]byte, error)
- func SchemaFromType(t reflect.Type, opts ...Option) (*highbase.SchemaProxy, error)
- func SchemaFromValue(value any, opts ...Option) (*highbase.SchemaProxy, error)
- type Diagnostic
- type Discriminator
- type ExternalRefResolver
- type GeneratedFile
- type GeneratedSourceFile
- type GeneratedType
- type Generator
- func (g *Generator) RenderSchema(name string, schema *highbase.SchemaProxy) ([]byte, error)
- func (g *Generator) RenderSchemas(schemas *orderedmap.Map[string, *highbase.SchemaProxy]) (*GeneratedFile, error)
- func (g *Generator) SchemaFromType(t reflect.Type) (*highbase.SchemaProxy, error)
- func (g *Generator) SchemaFromValue(value any) (*highbase.SchemaProxy, error)
- func (g *Generator) SchemasFromTypes(types ...reflect.Type) (*SchemaSet, error)
- func (g *Generator) SchemasFromValues(values ...any) (*SchemaSet, error)
- type Kind
- type NameResolver
- type Option
- func WithAdditionalPropertiesMethods(enabled bool) Option
- func WithDiscriminatorMapping(target any, property string, mapping map[string]string) Option
- func WithEnumConstants(enabled bool) Option
- func WithEnumValueNameResolver(resolver NameResolver) Option
- func WithExternalRefTypeResolver(resolver ExternalRefResolver) Option
- func WithFieldNameResolver(resolver NameResolver) Option
- func WithFieldSchema(t reflect.Type, fieldName string, schema *highbase.SchemaProxy) Option
- func WithFieldSchemaByJSONName(t reflect.Type, jsonName string, schema *highbase.SchemaProxy) Option
- func WithFormatMapping(format, goType, importPath string) Option
- func WithGenerateJSONTags(enabled bool) Option
- func WithGenerateYAMLTags(enabled bool) Option
- func WithGeneratedComment(enabled bool) Option
- func WithHeaderComment(text string) Option
- func WithNameResolver(resolver NameResolver) Option
- func WithNestedTypeNameDelimiter(delimiter string) Option
- func WithNullableAsPointer(enabled bool) Option
- func WithOmitEmpty(enabled bool) Option
- func WithOneOfTypes(target any, variants ...any) Option
- func WithOpenAPITags(enabled bool) Option
- func WithOptionalConstDiscriminatorUnions(enabled bool) Option
- func WithOptionalFieldsAsPointers(enabled bool) Option
- func WithPackageComment(text string) Option
- func WithPackageName(name string) Option
- func WithSchemaMetadataSidecar(enabled bool) Option
- func WithTypeNameResolver(resolver NameResolver) Option
- func WithTypeSchema(t reflect.Type, schema *highbase.SchemaProxy) Option
- type SchemaIR
- type SchemaMetadataProvider
- type SchemaProvider
- type SchemaSet
- type SchemaYAMLProvider
- type Source
- type UnionIR
- type UnionKind
- type UnionStrategy
Examples ¶
Constants ¶
const ( DiagnosticComponentNameCollision = "componentNameCollision" DiagnosticChildSchema = "childSchema" DiagnosticAdditionalPropertiesFalse = "additionalPropertiesFalse" DiagnosticArrayContains = "arrayContains" DiagnosticBooleanItems = "booleanItems" DiagnosticConstKeyword = "constKeyword" DiagnosticContentSchema = "contentSchema" DiagnosticDependentRequired = "dependentRequired" DiagnosticDependentSchemas = "dependentSchemas" DiagnosticDynamicReference = "dynamicReference" DiagnosticExternalReference = "externalReference" DiagnosticFieldNameCollision = "fieldNameCollision" DiagnosticConditionalSchema = "conditionalSchema" DiagnosticImplicitType = "implicitType" DiagnosticMixedEnum = "mixedEnum" DiagnosticMultiTypeSchema = "multiTypeSchema" DiagnosticNotSchema = "notSchema" DiagnosticNullEnum = "nullEnum" DiagnosticOptionalConstDiscriminator = "optionalConstDiscriminator" DiagnosticPatternProperties = "patternProperties" DiagnosticPrefixItems = "prefixItems" DiagnosticPropertyNames = "propertyNames" DiagnosticSchemaMetadata = "schemaMetadata" DiagnosticStringEncoded = "stringEncoded" DiagnosticTypeNameCollision = "typeNameCollision" DiagnosticUnevaluatedItems = "unevaluatedItems" DiagnosticRootNameCollision = "rootNameCollision" DiagnosticUnevaluatedProperties = "unevaluatedProperties" DiagnosticValidationKeyword = "validationKeyword" )
const SchemaMetadataFileName = "schema_metadata.go"
Variables ¶
Functions ¶
func RenderSchema ¶
RenderSchema renders a single OpenAPI schema as Go source.
Example ¶
properties := orderedmap.New[string, *highbase.SchemaProxy]()
properties.Set("id", highbase.CreateSchemaProxy(&highbase.Schema{Type: []string{"string"}}))
schema := highbase.CreateSchemaProxy(&highbase.Schema{
Type: []string{"object"},
Required: []string{"id"},
Properties: properties,
})
source, err := RenderSchema("Pet", schema, WithOptionalFieldsAsPointers(false))
if err != nil {
panic(err)
}
fmt.Println(strings.Contains(string(source), "type Pet struct"))
fmt.Println(strings.Contains(string(source), "ID string `json:\"id\"`"))
Output: true true
func SchemaFromType ¶
SchemaFromType generates an OpenAPI schema for a Go reflection type.
func SchemaFromValue ¶
func SchemaFromValue(value any, opts ...Option) (*highbase.SchemaProxy, error)
SchemaFromValue generates an OpenAPI schema for the runtime type of value.
Types ¶
type Diagnostic ¶
Diagnostic describes a notable generator decision.
type Discriminator ¶
type ExternalRefResolver ¶
ExternalRefResolver maps an external OpenAPI $ref to a Go type name. Returning an empty string falls back to deriving the type name from the reference tail.
type GeneratedFile ¶
type GeneratedFile struct {
PackageName string
Source []byte
SchemaMetadata *GeneratedSourceFile
Types []*GeneratedType
Diagnostics []Diagnostic
}
GeneratedFile contains Go source generated from OpenAPI schemas.
type GeneratedSourceFile ¶
GeneratedSourceFile contains a named generated source file.
type GeneratedType ¶
GeneratedType describes one top-level generated Go type.
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator holds immutable configuration for code generation. Each public entry point runs against a fresh copy of this configuration (see run), so a configured Generator carries no per-invocation state and is safe to reuse for many documents and to share across goroutines.
func NewGenerator ¶
NewGenerator creates a Go model generator.
func (*Generator) RenderSchema ¶
RenderSchema renders a single OpenAPI schema as Go source using this generator.
func (*Generator) RenderSchemas ¶
func (g *Generator) RenderSchemas(schemas *orderedmap.Map[string, *highbase.SchemaProxy]) (*GeneratedFile, error)
RenderSchemas renders an ordered map of OpenAPI schemas as one Go source file.
func (*Generator) SchemaFromType ¶
SchemaFromType generates an OpenAPI schema for a Go reflection type using this generator.
func (*Generator) SchemaFromValue ¶
func (g *Generator) SchemaFromValue(value any) (*highbase.SchemaProxy, error)
SchemaFromValue generates an OpenAPI schema for the runtime type of value using this generator.
func (*Generator) SchemasFromTypes ¶
SchemasFromTypes generates an OpenAPI component graph for Go reflection types using this generator.
Example ¶
generator := NewGenerator()
set, err := generator.SchemasFromTypes(reflect.TypeOf(ExampleCustomer{}))
if err != nil {
panic(err)
}
_, hasCustomer := set.Components.Get("ExampleCustomer")
_, hasAddress := set.Components.Get("ExampleBillingAddress")
fmt.Println(set.Root.GetReference())
fmt.Println(hasCustomer, hasAddress)
Output: #/components/schemas/ExampleCustomer true true
type NameResolver ¶
NameResolver maps OpenAPI names to Go identifiers. Returning an empty string falls back to the generator's default naming.
type Option ¶
type Option func(*Generator)
Option configures a Generator.
func WithAdditionalPropertiesMethods ¶
WithAdditionalPropertiesMethods controls whether schema-valued additionalProperties generates JSON marshal/unmarshal methods that round-trip unknown fields through the AdditionalProperties map.
func WithDiscriminatorMapping ¶
WithDiscriminatorMapping registers discriminator metadata for a reflected interface union.
func WithEnumConstants ¶
WithEnumConstants controls whether enum values generate Go constants.
func WithEnumValueNameResolver ¶
func WithEnumValueNameResolver(resolver NameResolver) Option
WithEnumValueNameResolver sets a resolver for generated enum constant suffixes.
func WithExternalRefTypeResolver ¶
func WithExternalRefTypeResolver(resolver ExternalRefResolver) Option
WithExternalRefTypeResolver sets a resolver for external OpenAPI $ref values when rendering Go type names. The resolver is not used for local component references.
func WithFieldNameResolver ¶
func WithFieldNameResolver(resolver NameResolver) Option
WithFieldNameResolver sets a resolver for generated Go struct field names.
func WithFieldSchema ¶
WithFieldSchema overrides reflected schema generation for a specific Go struct field name while keeping the surrounding model reflected normally.
func WithFieldSchemaByJSONName ¶
func WithFieldSchemaByJSONName(t reflect.Type, jsonName string, schema *highbase.SchemaProxy) Option
WithFieldSchemaByJSONName overrides reflected schema generation for a specific JSON field name while keeping the surrounding model reflected normally.
func WithFormatMapping ¶
WithFormatMapping maps an OpenAPI string format to a Go type and optional import path.
func WithGenerateJSONTags ¶
WithGenerateJSONTags controls generated json tags.
func WithGenerateYAMLTags ¶
WithGenerateYAMLTags controls generated yaml tags.
func WithGeneratedComment ¶
WithGeneratedComment writes a standard generated-code comment.
func WithHeaderComment ¶
WithHeaderComment writes a file header comment before the package clause.
func WithNameResolver ¶
func WithNameResolver(resolver NameResolver) Option
WithNameResolver sets a broad fallback resolver for generated Go names.
func WithNestedTypeNameDelimiter ¶
WithNestedTypeNameDelimiter sets the separator inserted between generated parent and child type names for inline schemas. The default is "_"; passing an empty delimiter restores compact names like ParentChild.
func WithNullableAsPointer ¶
WithNullableAsPointer controls whether nullable scalar fields render as pointers.
func WithOmitEmpty ¶
WithOmitEmpty controls omitempty on optional generated tags.
func WithOneOfTypes ¶
WithOneOfTypes registers concrete variants for a Go interface when producing OpenAPI oneOf schemas from reflection.
func WithOpenAPITags ¶
WithOpenAPITags controls whether generated struct fields include compact openapi tags for metadata that cannot be recovered from Go reflection alone.
func WithOptionalConstDiscriminatorUnions ¶
WithOptionalConstDiscriminatorUnions allows optional shared const discriminator properties to produce typed oneOf unions.
func WithOptionalFieldsAsPointers ¶
WithOptionalFieldsAsPointers controls whether optional scalar fields render as pointers.
func WithPackageComment ¶
WithPackageComment writes a package doc comment before the package clause.
func WithPackageName ¶
WithPackageName sets the generated Go package name.
func WithSchemaMetadataSidecar ¶
WithSchemaMetadataSidecar controls whether generated named types include a typed OpenAPISchemaMetadata sidecar. Enabling the sidecar preserves original OpenAPI schema fidelity for Go reflection round trips. Disabling it keeps the generated model code leaner, but OpenAPI -> Go -> OpenAPI reconstruction is intentionally lossy and falls back to Go type shape plus tags.
func WithTypeNameResolver ¶
func WithTypeNameResolver(resolver NameResolver) Option
WithTypeNameResolver sets a resolver for generated Go type names.
func WithTypeSchema ¶
func WithTypeSchema(t reflect.Type, schema *highbase.SchemaProxy) Option
WithTypeSchema overrides reflected schema generation for a specific Go type. This is useful for project scalar aliases that need a custom OpenAPI format, enum, or extension without implementing SchemaProvider on the type.
type SchemaIR ¶
type SchemaIR struct {
Name string
Ref string
Kind Kind
DynamicRef bool
Format string
Description string
Title string
Nullable bool
Required map[string]struct{}
Properties *orderedmap.Map[string, *SchemaIR]
PatternProperties *orderedmap.Map[string, *SchemaIR]
Items *SchemaIR
PrefixItems []*SchemaIR
AdditionalProperties *SchemaIR
AdditionalAllowed *bool
Enum []*yaml.Node
Const *yaml.Node
AllOf []*SchemaIR
Union *UnionIR
Extensions *orderedmap.Map[string, *yaml.Node]
Source *Source
ReadOnly bool
WriteOnly bool
Deprecated bool
FieldMetadata bool
ExactSource bool
Comments []string
SourceSchema *highbase.Schema
}
SchemaIR is the neutral hub both generation directions converge on. It carries two distinct channels. The shaping fields (Kind, Properties, Items, AdditionalProperties, Union, AllOf, Required, Nullable, Format, …) determine the generated Go type. SourceSchema carries the full original schema for the fidelity the IR does not model (validation keywords, conditionals, content, vocabulary, and so on); when ExactSource is set, openapiFromIR emits SourceSchema verbatim and ignores the shaping fields. FieldMetadata marks an IR whose SourceSchema should be rendered as $ref sibling metadata rather than inlined.
type SchemaMetadataProvider ¶
type SchemaMetadataProvider interface {
OpenAPISchemaMetadata() any
}
type SchemaProvider ¶
type SchemaProvider interface {
OpenAPISchema() *highbase.SchemaProxy
}
type SchemaSet ¶
type SchemaSet struct {
// Root is the first generated root schema, kept as a convenience for
// single-root callers.
Root *highbase.SchemaProxy
// Roots contains every requested root schema keyed by generated type name.
Roots *orderedmap.Map[string, *highbase.SchemaProxy]
// Components contains reusable schemas discovered while walking the root
// graph.
Components *orderedmap.Map[string, *highbase.SchemaProxy]
// Diagnostics reports schema features that required a lossy or notable
// model-generation decision.
Diagnostics []Diagnostic
}
SchemaSet contains OpenAPI schemas generated from one or more Go types.
func SchemasFromTypes ¶
SchemasFromTypes generates an OpenAPI component graph for Go reflection types.
func SchemasFromTypesWithOptions ¶
SchemasFromTypesWithOptions generates an OpenAPI component graph for Go reflection types using generator options.
func SchemasFromValues ¶
SchemasFromValues generates an OpenAPI component graph for runtime values.
type SchemaYAMLProvider ¶
type SchemaYAMLProvider interface {
OpenAPISchemaYAML() string
}
type UnionIR ¶
type UnionIR struct {
Kind UnionKind
Variants []*SchemaIR
Discriminator *Discriminator
Strategy UnionStrategy
FromMultiType bool
}
type UnionStrategy ¶
type UnionStrategy int
const ( UnionRawMessage UnionStrategy = iota UnionDiscriminator )