When the scanner emits a type
codescan does not emit a definition for every type it can see. A named type reaches the spec when either of these holds:
- it is reachable — referenced (directly or transitively) from an operation, parameter, response, or another emitted model; or
- it is registered — annotated
swagger:model, which (withOptions.ScanModels) publishes it even when nothing references it.
A type that is neither reachable nor registered is simply absent — the scanner never invents it. The package below has one of each case:
// Order is reached only through Cart below. A referenced named type is emitted
// as a $ref target even without swagger:model.
type Order struct {
// ID is the order identifier.
ID string `json:"id"`
}
// Cart references Order, so Order gets a definition and the field a $ref.
//
// swagger:model
type Cart struct {
// Order is the referenced (and therefore emitted) nested model.
Order Order `json:"order"`
}
// Standalone is never referenced, but swagger:model together with ScanModels
// publishes it anyway.
//
// swagger:model
type Standalone struct {
// Label is a free-text label.
Label string `json:"label"`
}
// Orphan is never referenced and carries no swagger:model — the scanner does
// not invent it, so it never reaches the spec.
type Orphan struct {
// Secret is internal.
Secret string `json:"secret"`
}Full source: docs/examples/shaping/discovery/discovery.go
Scanned with ScanModels: true, the definitions are:
{
"Cart": {
"type": "object",
"title": "Cart references Order, so Order gets a definition and the field a $ref.",
"properties": {
"order": {
"$ref": "#/definitions/Order"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/discovery"
},
"Order": {
"description": "Order is reached only through Cart below. A referenced named type is emitted\nas a $ref target even without swagger:model.",
"type": "object",
"properties": {
"id": {
"description": "ID is the order identifier.",
"type": "string",
"x-go-name": "ID"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/discovery"
},
"Standalone": {
"description": "Standalone is never referenced, but swagger:model together with ScanModels\npublishes it anyway.",
"type": "object",
"properties": {
"label": {
"description": "Label is a free-text label.",
"type": "string",
"x-go-name": "Label"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/discovery"
}
}
Full source: docs/examples/shaping/discovery/testdata/definitions.json
Cart— aswagger:modelroot.Order— has noswagger:model, yet it is emitted (as a$reftarget) becauseCartreferences it. You do not need to annotate every nested type.Standalone— aswagger:modelthat nothing references;ScanModelspublishes it anyway.Orphan— neither referenced nor annotated, so it never appears.
Info
If a model is missing from your spec, it is almost always unreachable: no
operation/parameter/response/model leads to it. Either reference it, or annotate
it swagger:model and scan with ScanModels.