diff --git a/openapi3gen/openapi3gen.go b/openapi3gen/openapi3gen.go index 960698324..84d1f998d 100644 --- a/openapi3gen/openapi3gen.go +++ b/openapi3gen/openapi3gen.go @@ -217,9 +217,21 @@ func (g *Generator) generateWithoutSaving(parents []*jsoninfo.TypeInfo, t reflec // If asked, try to use yaml tag name, fType := fieldInfo.JSONName, fieldInfo.Type if !fieldInfo.HasJSONTag && g.opts.useAllExportedFields { - ff := t.Field(fieldInfo.Index[len(fieldInfo.Index)-1]) - if tag, ok := ff.Tag.Lookup("yaml"); ok && tag != "-" { - name, fType = tag, ff.Type + // Handle anonymous fields/embedded structs + if t.Field(fieldInfo.Index[0]).Anonymous { + ref, err := g.generateSchemaRefFor(parents, fType) + if err != nil { + return nil, err + } + if ref != nil { + g.SchemaRefs[ref]++ + schema.WithPropertyRef(name, ref) + } + } else { + ff := t.Field(fieldInfo.Index[len(fieldInfo.Index)-1]) + if tag, ok := ff.Tag.Lookup("yaml"); ok && tag != "-" { + name, fType = tag, ff.Type + } } } diff --git a/openapi3gen/openapi3gen_test.go b/openapi3gen/openapi3gen_test.go index 777bb9dad..f8e2430e2 100644 --- a/openapi3gen/openapi3gen_test.go +++ b/openapi3gen/openapi3gen_test.go @@ -1,6 +1,7 @@ package openapi3gen import ( + "reflect" "testing" "github.com/getkin/kin-openapi/openapi3" @@ -53,3 +54,33 @@ func TestExportUint(t *testing.T) { "uint": {Value: &openapi3.Schema{Type: "integer", Min: &zeroInt}}, }}}, schemaRef) } + +func TestEmbeddedStructs(t *testing.T) { + type EmbeddedStruct struct { + ID string + } + + type ContainerStruct struct { + Name string + EmbeddedStruct + } + + instance := &ContainerStruct{ + Name: "Container", + EmbeddedStruct: EmbeddedStruct{ + ID: "Embedded", + }, + } + + generator := NewGenerator(UseAllExportedFields()) + + schemaRef, err := generator.GenerateSchemaRef(reflect.TypeOf(instance)) + require.NoError(t, err) + + var ok bool + _, ok = schemaRef.Value.Properties["Name"] + require.Equal(t, true, ok) + + _, ok = schemaRef.Value.Properties["ID"] + require.Equal(t, true, ok) +}