📖 7 min read (~ 1400 words).

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.

Annotated Go
// 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

#/definitions/Pet
{
  "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>}.

Annotated Go
// 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

#/definitions/Device
{
  "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.)

Annotated Go
// 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

#/definitions/Task
{
  "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.

Annotated Go
// 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

#/definitions/Dog
{
  "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.

Annotated Go
// 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

#/definitions/Token
{
  "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.

Annotated Go
// 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

#/definitions/Car
{
  "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