📖 5 min read (~ 1100 words).

Validations

Validations are keyword-driven: you write keyword: value lines in a field’s doc comment and they become minimum, maxLength, pattern, enum, and the rest of the validation surface on that property. Each pane below pairs the annotated Go (left) with the fragment the scanner emits (right), from the test-covered docs/examples/concepts/validations package.

For the per-keyword reference card — value shapes, aliases, and legal contexts — see Keywords.

On a model field — the full surface

A swagger:model field accepts the full JSON-schema validation vocabulary:

  • Numericminimum, maximum, multipleOf (on Price).
  • Lengthmin length / max length (on Name).
  • Arraysmin items / max items / unique (on Tags).
  • Pattern — a regular expression (on SKU).
  • Enum — a fixed value set (on Grade).
  • Requiredrequired: true lifts the property into the schema’s object-level required array (sku).
Annotated Go
// Product is a model whose fields carry the full JSON-schema validation surface.
//
// swagger:model
type Product struct {
	// SKU is the stock code.
	//
	// required: true
	// pattern: ^[A-Z]{3}-[0-9]{4}$
	SKU string `json:"sku"`

	// Price is the price in cents.
	//
	// minimum: 1
	// maximum: 1000000
	// multipleOf: 1
	Price int64 `json:"price"`

	// Name is the display name.
	//
	// min length: 1
	// max length: 120
	Name string `json:"name"`

	// Grade is a quality band.
	//
	// enum: A,B,C
	Grade string `json:"grade"`

	// Tags label the product.
	//
	// min items: 1
	// max items: 10
	// unique: true
	Tags []string `json:"tags"`
}

Full source: docs/examples/concepts/validations/validations.go

{
  "type": "object",
  "title": "Product is a model whose fields carry the full JSON-schema validation surface.",
  "required": [
    "sku"
  ],
  "properties": {
    "grade": {
      "description": "Grade is a quality band.",
      "type": "string",
      "enum": [
        "A",
        "B",
        "C"
      ],
      "x-go-name": "Grade"
    },
    "name": {
      "description": "Name is the display name.",
      "type": "string",
      "maxLength": 120,
      "minLength": 1,
      "x-go-name": "Name"
    },
    "price": {
      "description": "Price is the price in cents.",
      "type": "integer",
      "format": "int64",
      "maximum": 1000000,
      "minimum": 1,
      "multipleOf": 1,
      "x-go-name": "Price"
    },
    "sku": {
      "description": "SKU is the stock code.",
      "type": "string",
      "pattern": "^[A-Z]{3}-[0-9]{4}$",
      "x-go-name": "SKU"
    },
    "tags": {
      "description": "Tags label the product.",
      "type": "array",
      "maxItems": 10,
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "type": "string"
      },
      "x-go-name": "Tags"
    }
  },
  "x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/validations"
}

Full source: docs/examples/concepts/validations/testdata/field.json

On parameters — the simple-schema surface

Info

Simple schemas have a reduced surface. Parameters other than in: body, and response headers, are simple schemas in OpenAPI 2.0 — not full JSON schemas. They accept the validation subset (maximum/minimum/multipleOf, maxLength/minLength/pattern, maxItems/minItems/uniqueItems, enum, plus the simple-schema-only collectionFormat) but not schema-only constructs. A schema-only keyword such as readOnly placed on a query parameter is simply not emitted — spec.Parameter has nowhere to carry it.

A Go map field has no simple-schema representation either: on a non-body parameter or a response header it is skipped with a validate.unsupported-in-simple-schema warning. Maps are only representable on a body schema (as object + additionalProperties).

An array element is itself a simple schema, so it may not be a $ref. A named-primitive element ([]Label, underlying string) expands inline to its type; an object element ([]SomeStruct) has no simple-schema form and dissolves to an empty items: {} with the same warning. Use a body schema for an array of objects.

The same numeric and length keywords work on a query parameter; arrays add collectionFormat:

Annotated Go
// SearchParams is the simple-schema parameter set for searchProducts. Query
// parameters accept the reduced OAS 2.0 validation surface.
//
// swagger:parameters searchProducts
type SearchParams struct {
	// Q is the search text.
	//
	// in: query
	// min length: 3
	// max length: 50
	Q string `json:"q"`

	// Limit caps the number of results.
	//
	// in: query
	// minimum: 1
	// maximum: 100
	Limit int32 `json:"limit"`

	// Sort lists the sort fields.
	//
	// in: query
	// collection format: csv
	// unique: true
	Sort []string `json:"sort"`
}

Full source: docs/examples/concepts/validations/validations.go

parameters on searchProducts
[
  {
    "maxLength": 50,
    "minLength": 3,
    "type": "string",
    "x-go-name": "Q",
    "description": "Q is the search text.",
    "name": "q",
    "in": "query"
  },
  {
    "maximum": 100,
    "minimum": 1,
    "type": "integer",
    "format": "int32",
    "x-go-name": "Limit",
    "description": "Limit caps the number of results.",
    "name": "limit",
    "in": "query"
  },
  {
    "uniqueItems": true,
    "type": "array",
    "items": {
      "type": "string"
    },
    "collectionFormat": "csv",
    "x-go-name": "Sort",
    "description": "Sort lists the sort fields.",
    "name": "sort",
    "in": "query"
  }
]

Full source: docs/examples/concepts/validations/testdata/param.json

On response headers

A response header is also a simple schema, so it takes the same reduced validation set (here minimum on an integer header). Note headers carry no required flag.

Annotated Go
// RateLimited is a response carrying a validated header (a simple schema).
//
// swagger:response rateLimited
type RateLimited struct {
	// XRateRemaining is the remaining request budget.
	//
	// minimum: 0
	XRateRemaining int32 `json:"X-Rate-Remaining"`
}

Full source: docs/examples/concepts/validations/validations.go

responses[rateLimited]
{
  "description": "RateLimited is a response carrying a validated header (a simple schema).",
  "headers": {
    "X-Rate-Remaining": {
      "minimum": 0,
      "type": "integer",
      "format": "int32",
      "description": "XRateRemaining is the remaining request budget."
    }
  }
}

Full source: docs/examples/concepts/validations/testdata/header.json

On an object — property count and name patterns

The object-validation keywords constrain a free-form object as a whole rather than named fields: minProperties / maxProperties bound the property count, and patternProperties permits properties whose name matches a regex. They are schema-only — kept on an object-typed model, stripped (with a diagnostic) on a scalar model or a simple-schema parameter. For dynamic-key objects, the typed value forms, and additionalProperties, see Maps & free-form objects.

Annotated Go
// Attributes is a free-form object constrained by the object-validation
// keywords: it must carry between 1 and 10 properties, and any property whose
// name matches the regex is permitted. Object validations constrain the map of
// (additional) properties rather than named struct fields.
//
// minProperties: 1
// maxProperties: 10
// patternProperties: ^x-
//
// swagger:model Attributes
type Attributes map[string]any

Full source: docs/examples/concepts/validations/validations.go

#/definitions/Attributes
{
  "description": "Attributes is a free-form object constrained by the object-validation\nkeywords: it must carry between 1 and 10 properties, and any property whose\nname matches the regex is permitted. Object validations constrain the map of\n(additional) properties rather than named struct fields.",
  "type": "object",
  "maxProperties": 10,
  "minProperties": 1,
  "additionalProperties": {},
  "patternProperties": {
    "^x-": {}
  },
  "x-go-package": "github.com/go-openapi/codescan/docs/examples/concepts/validations"
}

Full source: docs/examples/concepts/validations/testdata/object.json

What’s next