Model definitions
A definitions entry is the most common thing you ask codescan to produce. This
page walks the annotations that create and shape one, from the plain
swagger:model struct to the per-type overrides. Each pane pairs the annotated
Go (left) with the exact fragment the scanner emits (right) — both come from the
test-covered docs/examples/concepts/models
package.
For the exhaustive rule on any annotation below, follow its link to the Maintainers reference.
swagger:model
swagger:model publishes a Go struct as a definition. Field doc comments become
property descriptions; json tags drive the property names; the Go type drives
the JSON-Schema type / format.
// Pet is a single pet in the store.
//
// swagger:model
type Pet struct {
// ID is the unique identifier.
ID int64 `json:"id"`
// Name is the pet's display name.
Name string `json:"name"`
// Tags categorise the pet.
Tags []string `json:"tags,omitempty"`
}Full source: docs/examples/concepts/models/models.go
{
"type": "object",
"title": "Pet is a single pet in the store.",
"properties": {
"id": {
"description": "ID is the unique identifier.",
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"name": {
"description": "Name is the pet's display name.",
"type": "string",
"x-go-name": "Name"
},
"tags": {
"description": "Tags categorise the pet.",
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Tags"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/models"
}
Full source: docs/examples/concepts/models/testdata/model.json
swagger:strfmt
swagger:strfmt <name> marks a named string type as a custom format. The type
does not become its own definition — instead, every field typed by it renders as
{type: string, format: <name>}.
// MAC is a hardware address rendered as a colon-separated hex string.
//
// swagger:strfmt mac
type MAC string
func (m MAC) MarshalText() ([]byte, error) { return []byte(m), nil }
func (m *MAC) UnmarshalText(b []byte) error { *m = MAC(b); return nil }
// Device exposes a strfmt-typed field: wherever MAC appears it renders inline
// as {type: string, format: mac}.
//
// swagger:model
type Device struct {
// Addr is the hardware address.
Addr MAC `json:"addr"`
}Full source: docs/examples/concepts/models/models.go
{
"description": "Device exposes a strfmt-typed field: wherever MAC appears it renders inline\nas {type: string, format: mac}.",
"type": "object",
"properties": {
"addr": {
"description": "Addr is the hardware address.",
"type": "string",
"format": "mac",
"x-go-name": "Addr"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/models"
}
Full source: docs/examples/concepts/models/testdata/strfmt.json
swagger:enum
swagger:enum <name> collects the type’s const values. When a model field
references the type, the property carries the enum array and an
x-go-enum-desc extension built from the per-value doc comments. (The enum type
is reachable, and so emitted, only because a model field points at it.)
// Priority is the urgency level on a task.
//
// swagger:enum Priority
type Priority string
const (
// PriorityLow is for tasks that can wait.
PriorityLow Priority = "low"
// PriorityMedium is the default.
PriorityMedium Priority = "medium"
// PriorityHigh is for tasks that must run soon.
PriorityHigh Priority = "high"
)
// Task is a unit of work carrying an enum-typed field. Referencing Priority
// from a model is what makes the enum reachable, and so emitted.
//
// swagger:model
type Task struct {
// Priority is the task's urgency.
Priority Priority `json:"priority"`
}Full source: docs/examples/concepts/models/models.go
{
"description": "Task is a unit of work carrying an enum-typed field. Referencing Priority\nfrom a model is what makes the enum reachable, and so emitted.",
"type": "object",
"properties": {
"priority": {
"description": "Priority is the task's urgency.\nlow PriorityLow is for tasks that can wait.\nmedium PriorityMedium is the default.\nhigh PriorityHigh is for tasks that must run soon.",
"type": "string",
"enum": [
"low",
"medium",
"high"
],
"x-go-enum-desc": "low PriorityLow is for tasks that can wait.\nmedium PriorityMedium is the default.\nhigh PriorityHigh is for tasks that must run soon.",
"x-go-name": "Priority"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/models"
}
Full source: docs/examples/concepts/models/testdata/enum.json
swagger:allOf
Embedding base types under swagger:allOf composes a schema. Each embedded base
becomes a $ref arm of the allOf; the struct’s own (non-embedded) fields form
a final inline arm. That last arm is inline rather than a $ref because those
fields are new to this type — they belong to no existing definition to point at.
Here Dog embeds two bases (Animal, Tagged) and adds breed, producing
three arms: two $refs and one inline object.
// Animal is one abstract base.
//
// swagger:model
type Animal struct {
// Kind discriminates the animal.
Kind string `json:"kind"`
}
// Tagged is a second reusable base.
//
// swagger:model
type Tagged struct {
// Tags label the resource.
Tags []string `json:"tags"`
}
// Dog composes two base models plus its own fields: each embedded base becomes
// a $ref arm of the allOf, and the struct's own (non-embedded) fields — which
// are new and cannot be a $ref — form the final inline arm.
//
// swagger:model
type Dog struct {
// swagger:allOf
Animal
// swagger:allOf
Tagged
// Breed is the dog's breed.
Breed string `json:"breed"`
}Full source: docs/examples/concepts/models/models.go
{
"description": "Dog composes two base models plus its own fields: each embedded base becomes\na $ref arm of the allOf, and the struct's own (non-embedded) fields — which\nare new and cannot be a $ref — form the final inline arm.",
"allOf": [
{
"$ref": "#/definitions/Animal"
},
{
"$ref": "#/definitions/Tagged"
},
{
"type": "object",
"properties": {
"breed": {
"description": "Breed is the dog's breed.",
"type": "string",
"x-go-name": "Breed"
}
}
}
],
"x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/models"
}
Full source: docs/examples/concepts/models/testdata/allof.json
swagger:type
swagger:type <type> overrides the type codescan would infer. Here a [16]byte
field is published as a string.
// ULID is a 128-bit identifier stored as bytes but rendered as a string.
//
// swagger:type string
type ULID [16]byte
// Token carries a field whose inferred type is overridden, inline.
//
// swagger:model
type Token struct {
// ID renders as a string despite its [16]byte Go type.
ID ULID `json:"id"`
}Full source: docs/examples/concepts/models/models.go
{
"type": "object",
"title": "Token carries a field whose inferred type is overridden, inline.",
"properties": {
"id": {
"description": "ID renders as a string despite its [16]byte Go type.",
"type": "string",
"x-go-name": "ID"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/models"
}
Full source: docs/examples/concepts/models/testdata/type.json
The accepted values are the scalar Swagger types — string, integer,
number, boolean, object (plus the Go builtin names codescan resolves).
array and file are not accepted here; an unrecognized value leaves the field
on its underlying Go type.
swagger:name
A model defined as an interface publishes one property per nullary method.
By default the property name is the camelCased method name — so Maker()
already becomes maker with no annotation. swagger:name <name> is the
override for when that default is not what you want (interface methods
cannot carry a json tag). Here StructType() would default to structType;
the annotation publishes it as jsonClass instead.
// Car is exposed as a schema via its method set. Interface methods cannot carry
// a json tag, so by default each property takes the camelCased method name;
// swagger:name overrides that where the default is not what you want.
//
// swagger:model
type Car interface {
// Maker is the manufacturer. With no override the property is the
// camelCased method name, "maker".
Maker() string
// StructType is the polymorphic class. Without the override the property
// would be "structType"; swagger:name publishes it as "jsonClass".
//
// swagger:name jsonClass
StructType() string
}Full source: docs/examples/concepts/models/models.go
{
"description": "Car is exposed as a schema via its method set. Interface methods cannot carry\na json tag, so by default each property takes the camelCased method name;",
"type": "object",
"properties": {
"jsonClass": {
"description": "StructType is the polymorphic class. Without the override the property\nwould be \"structType\"; swagger:name publishes it as \"jsonClass\".",
"type": "string",
"x-go-name": "StructType"
},
"maker": {
"description": "Maker is the manufacturer. With no override the property is the\ncamelCased method name, \"maker\".",
"type": "string",
"x-go-name": "Maker"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/models"
}
Full source: docs/examples/concepts/models/testdata/name.json
swagger:ignore
swagger:ignore drops a declaration from the output. The scanner sees Secret,
classifies it, then excludes it — so it never reaches the definitions (a fact
the example’s TestIgnoreOmitsType asserts).
// Secret never reaches the spec.
//
// swagger:ignore
type Secret struct {
// Token is internal.
Token string `json:"token"`
}Full source: docs/examples/concepts/models/models.go
What’s next
- Routes & operations — wire these models into paths, parameters and responses.
- Validations — constrain field values with keyword annotations.
- Shaping the output — alias handling,
$refvs inline, nullable pointers and more.