Keeping annotations out of the godoc
A godoc comment and an API description pursue different goals. The godoc is for
the Go developers reading the package; the API text is for the consumers of the
generated spec. By default codescan reads its annotations from the doc comment
above a declaration, which mixes the two concerns — a swagger:model,
maxProperties: or swagger:strfmt line sits right in the middle of the prose a
Go reader sees.
AfterDeclComments separates them. With the option on, codescan also reads
annotations placed inside a struct body (its leading comment) or inlined as
a trailing comment on the same line as the declaration. The godoc above stays
concise and human-facing while the swagger machinery lives out of it — same
annotation grammar, no new syntax. It is the placement counterpart to
overriding titles & descriptions,
which separates the same two concerns at the text level.
Each pane below pairs the annotated Go (left) with the exact fragment the scanner
emits (right), from the test-covered
docs/examples/shaping/afterdecl
package.
Inside a struct body, or trailing on a field
The swagger:model annotation (and any decl-level keyword such as
maxProperties:) can live as the leading comment inside the struct body,
above the first field. A field-level annotation like swagger:strfmt can ride a
trailing comment on the field line. The godoc above Widget says nothing
about swagger:
// Widget is a widget. This godoc stays clean — no swagger machinery here.
type Widget struct {
// Widget is exposed to API consumers.
//
// swagger:model widgetModel
// maxProperties: 5
Name string `json:"name"`
// Created is documented with a clean godoc; the format annotation is
// inlined as a trailing comment.
Created string `json:"created"` // swagger:strfmt date
}Full source: docs/examples/shaping/afterdecl/afterdecl.go
Inlined on a defined type or alias
For a non-struct type — a defined type or a type alias — the annotation rides a trailing comment after the declaration:
// Count is a plain count. Clean godoc above; annotation inlined below.
type Count int // swagger:model countType
// Stamp is a string alias. Clean godoc above; annotation inlined trailing.
type Stamp = string // swagger:model stampTypeFull source: docs/examples/shaping/afterdecl/afterdecl.go
Turning it on
AfterDeclComments is opt-in and defaults to off — so existing code, where a
clean comment that happens to look like an annotation is just prose, is never
reinterpreted:
With the option off, the inside-body and trailing annotations above are inert
— the clean godoc carries no annotation, so nothing is discovered. With it
on, the same source yields the three definitions, each with its keywords
applied (and the clean godoc still supplies the human-facing title):
{
"countType": {
"type": "integer",
"format": "int64",
"title": "Count is a plain count. Clean godoc above; annotation inlined below.",
"x-go-name": "Count",
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/afterdecl"
},
"stampType": {
"type": "string",
"title": "Stamp is a string alias. Clean godoc above; annotation inlined trailing.",
"x-go-name": "Stamp",
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/afterdecl"
},
"widgetModel": {
"description": "Widget is exposed to API consumers.",
"type": "object",
"title": "Widget is a widget. This godoc stays clean — no swagger machinery here.",
"maxProperties": 5,
"properties": {
"created": {
"description": "Created is documented with a clean godoc; the format annotation is\ninlined as a trailing comment.",
"type": "string",
"format": "date",
"x-go-name": "Created"
},
"name": {
"type": "string",
"x-go-name": "Name"
}
},
"x-go-name": "Widget",
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/afterdecl"
}
}
Full source: docs/examples/shaping/afterdecl/testdata/on.json
Info
Scope (v0.36). The opt-in covers type declarations — a struct’s
inside-body leading comment, a struct field’s trailing comment, and the trailing
comment of a defined type or alias. Routes and operations are already
position-agnostic: a swagger:route / swagger:operation block inside a
function body is discovered with or without this option. Const-based enums are a
planned follow-up.
What’s next
- Overriding titles & descriptions — separate the godoc and the API text at the content level.
- Single-line comments
— how a plain comment is routed to
titlevsdescription.