📖 3 min read (~ 600 words).

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: IDid, CreatedAtcreatedAt. 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:

Default — jsonified
{
  "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

SkipJSONifyInterfaceMethods — 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"
    },
    "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 the x-go-name extension.
  • With the opt-out, the Go name is the property name. ID and CreatedAt appear verbatim — and x-go-name drops, since it would now just repeat the property name.
  • A swagger:name override is verbatim either way. OverriddenField is published as explicit_name in both panes — the override already bypasses the mangler, so the flag never touches it (and never re-mangles it to explicitName).
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