The x-constants block

x-constants is an OpenAPI specification extension. OpenAPI allows any top-level key that starts with x-, and tools that do not know the key ignore it. oapixconstgen reads only this key. Inside it, each key is a Go type and each entry under that type is one constant.

x-constants:
  int:
    defaultPageSize: &defaultPageSize 20
    maxPageSize: &maxPageSize 100
  uint:
    minPasswordLength: &minPasswordLength 8
  float64:
    requestTimeout: &requestTimeout 30.5
  string:
    defaultLocale: &defaultLocale "en-US"
  bool:
    enableCache: &enableCache true

The anchors (&defaultPageSize) are plain YAML. The tool does not need them; they are there so the rest of the spec can reuse the value with an alias such as *defaultPageSize. YAML resolves aliases when the file is parsed, so every OpenAPI tool that reads the spec sees the literal value.

That block generates:

// Code generated by oapixconstgen. DO NOT EDIT.

package api

const (
	DefaultLocale     string  = "en-US"
	DefaultPageSize   int     = 20
	EnableCache       bool    = true
	MaxPageSize       int     = 100
	MinPasswordLength uint    = 8
	RequestTimeout    float64 = 30.5
)

Type keys

The type key is used as the Go type unchanged. These 14 are supported:

Type key Go type Written with
int int %d
int8 int8 %d
int16 int16 %d
int32 int32 %d
int64 int64 %d
uint uint %d
uint8 uint8 %d
uint16 uint16 %d
uint32 uint32 %d
uint64 uint64 %d
float32 float32 %v
float64 float64 %v
string string %q
bool bool %t

Any other key under x-constants is skipped without a warning. Its value still has to be a map, though, because the whole block is parsed as a map of maps before the keys are looked at. A skipped key that holds a scalar or a list fails the run with failed to parse spec file.

Values

The tool formats each value with the verb in the table above, applied to whatever the YAML parser returned. The tool does not check that the value fits the type key, so:

  • Integers are written as decimal digits. The full uint64 range works, for example 18446744073709551615.
  • Floats are written in Go’s shortest form: 30.5, 0 for 0.0, 1e+21, 1e-30. An integer under a float key works too.
  • Strings are written as Go double-quoted literals with escapes, so quotes and backslashes in the value are safe.
  • Booleans must be YAML 1.2 true or false. The parser reads yes, on and similar words as strings.

A value of the wrong kind, such as 1.5 under int, yes under bool, or an empty value, produces text that is not Go. go/format rejects it, and the run fails with failed to generate code before any file is written. One mismatch gets through: a number under string is written as a rune literal (20 becomes '\x14'). The file is written, and the Go compiler rejects it later. Quote numbers that are meant as strings.

Range is not checked either. 300 under uint8 is written as is, and the Go compiler reports the overflow when the package is built.

Names

The tool splits each name on underscores and upper-cases the first byte of every part. Nothing else changes:

Name in the spec Go constant
defaultLimit DefaultLimit
max_page_size MaxPageSize
api_version ApiVersion
already_Capitalized AlreadyCapitalized

Initialisms are not recognized, so write apiVersion if you want ApiVersion and APIVersion if you want APIVersion. Keep names to ASCII letters, digits and underscores, starting with a letter. A hyphen, a space or a leading digit gives a name that is not a Go identifier, and the run fails with failed to generate code.

Names have to be unique across the whole block, after conversion. The same name under two type keys, or max_size next to maxSize, produces two constants with one name. That parses, so the file is written, and the Go compiler reports the redeclaration.

Order

The tool sorts constants by the name as written in the spec, in byte order, so names that start with an upper-case letter come before lower-case ones. The type key plays no part in the order, and go/format aligns the columns. Two runs on the same spec produce the same file, which keeps diffs of the generated file limited to real changes.