Interface-method property names
When a model’s shape is described by an interface, its methods have no
natural JSON serialization — Go’s encoding/json can’t marshal interface
methods, so there’s no struct tag to read a name from. codescan invents one by
running its jsonify transform on the Go method name: ID → id, CreatedAt
→ createdAt. That “one size fits all” convention isn’t always what you want —
an interface already named for its JSON shape, or a codebase with its own
canonical-name discipline, wants the Go name kept as-is.
SkipJSONifyInterfaceMethods opts out of the mangler. With it set, an
interface-method property is emitted under the Go method name verbatim. It is an
opt-out and defaults to off; with it off, output is unchanged.
What changes
This model is an interface with two default-path methods and one carrying a
swagger:name override:
// Account is a read model whose shape is described by interface methods.
//
// swagger:model Account
type Account interface {
// ID is emitted as "id" by default; verbatim "ID" with the opt-out set.
ID() string
// CreatedAt is emitted as "createdAt" by default; verbatim "CreatedAt" with
// the opt-out set.
CreatedAt() string
// swagger:name explicit_name
//
// A swagger:name override is taken verbatim either way — re-mangling would
// camelCase it to "explicitName".
OverriddenField() string
}Full source: docs/examples/shaping/interfacenames/interfacenames.go
Scanned with the flag off the method names auto-jsonify; on, they ride through verbatim:
{
"type": "object",
"title": "Account is a read model whose shape is described by interface methods.",
"properties": {
"createdAt": {
"description": "CreatedAt is emitted as \"createdAt\" by default; verbatim \"CreatedAt\" with\nthe opt-out set.",
"type": "string",
"x-go-name": "CreatedAt"
},
"explicit_name": {
"description": "\nA swagger:name override is taken verbatim either way — re-mangling would\ncamelCase it to \"explicitName\".",
"type": "string",
"x-go-name": "OverriddenField"
},
"id": {
"description": "ID is emitted as \"id\" by default; verbatim \"ID\" with the opt-out set.",
"type": "string",
"x-go-name": "ID"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/interfacenames"
}
Full source: docs/examples/shaping/interfacenames/testdata/account_off.json
{
"type": "object",
"title": "Account is a read model whose shape is described by interface methods.",
"properties": {
"CreatedAt": {
"description": "CreatedAt is emitted as \"createdAt\" by default; verbatim \"CreatedAt\" with\nthe opt-out set.",
"type": "string"
},
"ID": {
"description": "ID is emitted as \"id\" by default; verbatim \"ID\" with the opt-out set.",
"type": "string"
},
"explicit_name": {
"description": "\nA swagger:name override is taken verbatim either way — re-mangling would\ncamelCase it to \"explicitName\".",
"type": "string",
"x-go-name": "OverriddenField"
}
},
"x-go-package": "github.com/go-openapi/codescan/docs/examples/shaping/interfacenames"
}
Full source: docs/examples/shaping/interfacenames/testdata/account_on.json
Reading the two panes:
- Default-path methods are jsonified.
ID()→id,CreatedAt()→createdAt; the original Go name is preserved as thex-go-nameextension. - With the opt-out, the Go name is the property name.
IDandCreatedAtappear verbatim — andx-go-namedrops, since it would now just repeat the property name. - A
swagger:nameoverride is verbatim either way.OverriddenFieldis published asexplicit_namein both panes — the override already bypasses the mangler, so the flag never touches it (and never re-mangles it toexplicitName).
Note
This flag only affects interface methods, which have no JSON serialization to
mirror. Struct-field property names are untouched — they always reflect what
encoding/json actually produces (see
Naming from struct tags to source those from
a different tag).
What’s next
- Naming from struct tags — choose which struct tag a field name comes from (the struct-field analogue of this knob).
- Resolving
$refname conflicts — how the definition names themselves are kept distinct.