📖 3 min read (~ 600 words).

Putting it together

This capstone scans a tiny annotated “petstore” package and produces a Swagger 2.0 spec — the concepts from the pages above, assembled into one runnable example. It is the worked version of usage as a library.

The annotated API

A package-level swagger:meta block sets the top-level metadata:

// Package petstore Petstore API
//
// A tiny pet store, used to demonstrate codescan annotations: the package
// comment is a `swagger:meta` block carrying the top-level metadata of the
// generated specification (title, description, version, base path, …).
//
//	Schemes: https
//	Version: 1.0.0
//	BasePath: /v1
//
//	Consumes:
//	- application/json
//
//	Produces:
//	- application/json
//
// swagger:meta

Full source: docs/examples/petstore/doc.go

A swagger:route registers a path and ties it to a response:

// swagger:route GET /pets pets listPets
//
// Lists all the pets in the store.
//
// responses:
//
//	200: petsResponse

Full source: docs/examples/petstore/pet.go

A swagger:model struct becomes a definition, with field comments driving validations:

// Pet is a single pet in the store.
//
// swagger:model Pet
type Pet struct {
	// The id of the pet.
	//
	// required: true
	// minimum: 1
	ID int64 `json:"id"`

	// The name of the pet.
	//
	// required: true
	// min length: 1
	Name string `json:"name"`

	// The tags associated with this pet.
	Tags []string `json:"tags,omitempty"`
}

Full source: docs/examples/petstore/pet.go

Running the scan

ScanPetstore builds the Options and calls codescan.Run:

opts := &codescan.Options{
	WorkDir:    workDir,                // module root to resolve patterns from
	Packages:   []string{"./petstore"}, // relative package pattern
	ScanModels: true,                   // also emit definitions for swagger:model types
}

doc, err := codescan.Run(opts)
if err != nil {
	return nil, err
}

Full source: docs/examples/basic/scan.go

The generated spec

Marshalling the returned *spec.Swagger to JSON yields the document below — the meta block became the top-level info / basePath, the swagger:route became the /pets path, and the swagger:model became the Pet definition:

{
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "schemes": [
    "https"
  ],
  "swagger": "2.0",
  "info": {
    "description": "A tiny pet store, used to demonstrate codescan annotations: the package\ncomment is a `swagger:meta` block carrying the top-level metadata of the\ngenerated specification (title, description, version, base path, …).",
    "title": "Petstore API",
    "version": "1.0.0"
  },
  "basePath": "/v1",
  "paths": {
    "/pets": {
      "get": {
        "tags": [
          "pets"
        ],
        "summary": "Lists all the pets in the store.",
        "operationId": "listPets",
        "responses": {
          "200": {
            "$ref": "#/responses/petsResponse"
          }
        }
      }
    }
  },
  "definitions": {
    "Pet": {
      "type": "object",
      "title": "Pet is a single pet in the store.",
      "required": [
        "id",
        "name"
      ],
      "properties": {
        "id": {
          "description": "The id of the pet.",
          "type": "integer",
          "format": "int64",
          "minimum": 1,
          "x-go-name": "ID"
        },
        "name": {
          "description": "The name of the pet.",
          "type": "string",
          "minLength": 1,
          "x-go-name": "Name"
        },
        "tags": {
          "description": "The tags associated with this pet.",
          "type": "array",
          "items": {
            "type": "string"
          },
          "x-go-name": "Tags"
        }
      },
      "x-go-package": "github.com/go-openapi/codescan/docs/examples/petstore"
    }
  },
  "responses": {
    "petsResponse": {
      "description": "petsResponse is the list of pets returned by listPets.",
      "schema": {
        "type": "array",
        "items": {
          "$ref": "#/definitions/Pet"
        }
      }
    }
  }
}

Full source: docs/examples/basic/testdata/swagger.json

This JSON is not hand-written: it is a golden file the example’s test regenerates and compares on every run (UPDATE_GOLDEN=1 go test ./...). Because the example is ordinary, test-covered Go, go test ./docs/examples/... keeps the page honest — if the scanner’s output changes, CI fails before the documentation can go stale.