Read Partial YAML Into Schema #557
-
|
Hi. I'm trying to build a valid OpenAPI v3.1.0 document from partial YAML. The partial YAML comes from a different YAML document that has sections containing Components. I've been able to parse that original document and iterate over the sections that contain components. However, now I need to create new Schemas (or SchemaProxies) from the YAML that I have. Can you provide an example of how I'm supposed to do that? I already have the []byte representing the YAML. Prior to that, I had a K8S JSONSchemaProps (I'm trying to extract data from a CRD type that contains the partial OpenAPI spec). I had this working using kin-openapi but then discovered that library didn't support OpenAPI 3.1 features that I need. So I have been trying to migrate to libopenapi. To start with, I have an []byte that has the following content: properties:
displayName:
description: Name to display on user screens ([a-zA-Z0-9 _-]).
pattern: ^[a-zA-Z0-9][a-zA-Z0-9_\- ]+[a-zA-Z0-9]$
type: string
required:
- displayName
type: objectFrom what I could find in your test code, I think I should be able to do something like this: var rootNode yaml.Node
err = yaml.Unmarshal(b, &rootNode)
if err != nil {
c.logger.Fatal("Error unmarshalling JSONSchemaProps", zap.Error(err))
}
lowSchema := &lowbase.Schema{}
err = low.BuildModel(rootNode.Content[0], lowSchema)
if err != nil {
c.logger.Fatal("Error building model", zap.Error(err))
}I wasn't sure where to go from there. I had started creating the new high document: doc := &v3.Document{
Version: "3.1.0",
Info: &highbase.Info{
Title: kind,
Version: versionName,
},
Components: &v3.Components{
Schemas: orderedmap.New[string, *highbase.SchemaProxy](),
},
}But was unsure of how I was going to create the highbase.SchemaProxy to add to my document. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
You're almost there! The missing piece is the import (
"context"
highbase "github.com/pb33f/libopenapi/datamodel/high/base"
"github.com/pb33f/libopenapi/datamodel/low"
lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
v3 "github.com/pb33f/libopenapi/datamodel/high/v3"
"github.com/pb33f/libopenapi/orderedmap"
"go.yaml.in/yaml/v4"
)
// Unmarshal your partial YAML into a yaml.Node tree
var rootNode yaml.Node
if err := yaml.Unmarshal(b, &rootNode); err != nil {
log.Fatal(err)
}
// BuildModel maps simple scalar fields via reflection
var lowSchema lowbase.Schema
if err := low.BuildModel(rootNode.Content[0], &lowSchema); err != nil {
log.Fatal(err)
}
// Build() processes properties, type, required, allOf, etc.
// This is the step you were missing!
if err := lowSchema.Build(context.Background(), rootNode.Content[0], nil); err != nil {
log.Fatal(err)
}
// Create the high-level Schema from the low-level one
highSchema := highbase.NewSchema(&lowSchema)
// Wrap in a SchemaProxy — this is what Components.Schemas expects
proxy := highbase.CreateSchemaProxy(highSchema)
// Add to your document
doc := &v3.Document{
Version: "3.1.0",
Info: &highbase.Info{
Title: kind,
Version: versionName,
},
Components: &v3.Components{
Schemas: orderedmap.New[string, *highbase.SchemaProxy](),
},
}
doc.Components.Schemas.Set("MySchema", proxy)
|
Beta Was this translation helpful? Give feedback.
You're almost there! The missing piece is the
Build()call on the low-level schema.BuildModel()only handles simple scalar fields via reflection.Build()is what processes the complex nested structures like properties, type, polymorphic keywords.