docs/reference/models/schemas.md
Lots of the work carried out by go-swagger is to generate models, which can have all kinds of rules like polymorphism and validations. Go-swagger models are the go data structures used for serialization and validation.
Of course none of this is possible without a set of rules and trade-offs.
A schema is a data structure specified in a Swagger document. Loosely speaking, a swagger schema corresponds to
a JSONSchema-draft4 schema (see differences below).
For each schema, go-swagger will generate one or more model types in go.
NOTE: Swagger makes a distinction between schemas and "simple schemas". We use simple schemas to describe parameters and headers for operations. Simple schemas are supported by
go-swagger(including validation), but are not rendered as standalone models. Rather, simple schema structures and validation methods are generated with the operation they are attached to.Models are dedicated to the description of Swagger schemas, which are described as a parameter body, a response or a spec definition.
The generated models implements:
MarshalJSON(), UnmarshalJSON():
allOf, additionalProperties, tuples and polymorphic types)MarshalBinary(), UnmarshalBinary() interfaces (encoding/BinaryMarshaler, encoding/BinaryUnmarshaler),
which may use the fast mailru/easyjson packagego-openapi/runtime/Validatable), with a Validate(strfmt.Registry) error methodValidation methods are wired at generation time, and rely mostly on native types: this makes validation faster than a dynamic general purpose JSON schema validator.
Example of a generated structure:
// Principal principal
// swagger:model principal
type Principal struct {
// name
Name string `json:"name,omitempty"`
// roles
Roles []string `json:"roles"`
}
NOTE: if you are looking for a dynamic, fully JSONSchema compliant, general purpose validator, the
go-openapi/validatepackage is what you want. It is fully tested against the JSONSchema-Test-Suite (supports JSON-schema-draft4). See a working example here.
The general idea is that you should rarely see interface{} in the generated code:
you get a complete representation of a swagger document in somewhat idiomatic go.
There is set of mapping patterns that are applied to transform a spec into go types:
x-isnullable: true or x-nullable: true turns
the schema into a pointer when there are only other extension properties providedGenerated models uses no reflection except for enum and required validations. This makes validation faster.
All documentation items provided by the spec are integrated as godoc-friendly comments in the generated source. You may look at how a trivial example is rendered here.
The code that is generated also gets the same doc comments that are used by the scanner
to generate a spec from go code (e.g. comments like // swagger:xxx).
So that after generation you should be able to reverse-generate a spec from the code that was generated by your spec.
It should be equivalent to the original spec but might miss some default values and examples.
Models can be generated independently from other components of your API. Internal model structures may thus be safely regenerated if the contract at your endpoints does not change.
Previously generated models can be reused when constructing a new API server or client (e.g. using swagger generate server --model=[my existing package]).
The generator makes every effort to keep the go code readable, idiomatic and commented: models may thus be manually customized or extended.
Such customized types may be later on reused in other specs, using the x-go-type extension.
A Swagger 2.0 schema corresponds by and large to a JSON-schema-draft4. However, there are some substantial differences (see swagger):
In JSONSchema, but not in Swagger 2.0:
anyOf, oneOf and not constructs are not supported (this is for OpenAPI 3)null type is not supported (the nullable keyword is defined in OpenAPI 3)additionalItems are not supported (go-swagger does support it)patternProperties are not supporteddependencies are not supportedtype: [ ... ] are not supportedConversely, what we have in Swagger 2.0, but not in JSON-schema:
discriminator attribute controls polymorphism (see below)readOnly attribute (same as in JSONSchema-draft7)array types must have an items restrictionformat supports more values for strings and numbersOther minor differences:
default values must validate their schemaarray must have an items specificationx-... annotations. Go-swagger defines some custom tags to customize generated code.example, xml and externalDocsNOTE:
exampleandexternalDocsdo not currently influence models generation.
go-swagger models implements almost all Swagger 2.0 schema features.
We also wanted to support as much JSONSchema features as possible: the model generator may be used independently to generate data structures using the Swagger specification as a serialization description language.
There are some small differences or implementation details to be aware of.
| Feature | JSON-schema-draft4 | Swagger 2.0 | go-swagger | Comment |
|---|---|---|---|---|
"format" | Y | Y | Y | Formats are provided by the extensible go-openapi/strfmt package. See also here |
"additionalProperties": {schema} | Y | Y | Y | Rendered as map[string]T |
"additionalProperties": boolean | Y | Y | partial | Rendered as map[string]interface{} |
"additionalItems": {schema} | Y | N | Y | Rendered with tuple models |
"additionalItems": boolean | Y | N | partial | See extensible types |
empty object: { "type": "object"} | Y | Y | Y | Rendered as interface{} (anything) rather than map[string]inferface{} (any JSON object, e.g. not arrays) |
"pattern" | Y | Y | partial | Speed for strictness trade-off: support go regexp, which slighty differ from JSONSchema ECMA regexp (e.g does not support backtracking) |
| large number, arbitrary precision | Y | N | N | |
"readOnly" | N | Y | Y | |
"type": [ "object", ... ] | Y | N | N | JSONSchema multiple types are not supported: use Swagger polymorphism instead |
implicit type from values in enum | Y | ? | N | As of v0.15, when the type is empty, the object is rendered as interface{} and the enum constraint is ignored |
| tuple `type: "array" items:[...] | Y | Y | partial | As of v0.15, incomplete tuples and tuples with array validation are not properly validated |
JSONSchema defaults to "additionalProperties": true, go-swagger defaults to ignoring extra properties. Same for additionalItems.
When"additionalProperties": false (resp. "additionalItems": false), uwanted properties (resp. items) do not invalidate data
but they are not kept in the model.
This is the default if additionalProperties (resp. additionalItems) is not provided.
It is an optimization as it makes the code simpler (and faster) for most use cases.
Explicitly specifying true will produce models that retain those additional properties (resp. items).
Recap as of release >0.26:
"additionalProperties": false, "additionalItems": false do not invalidate data with extra properties. We trade strictness for speed and
truncate unwanted properties or items without further validation.--strict-additional-properties invalidates data with extra properties when "additionalProperties": falseenum values cannot be marshalled into their schema, a runtime panic occurs - the go-openapi/validate package does not yet detect this situationpatternProperties and dependenciesare not supportedadditionalItems requires the --skip-validation flag (go-openapi/validate is strict regarding Swagger specification)"additionalProperties": true, go-swagger defaults to ignoring extra properties. Same for additionalItems.minItems, etc.) are not yet supported for tuples, as of v0.15interface{})null JSON type: the null type is not supported by Swagger - use of the x-nullable extension makes null values valid
(notice that combining the use of required and x-nullable is not fully JSONSchema compliant - see below)Model generation may be altered with the following extensions:
x-go-name: "string": give explicit type name to the generated modelx-go-custom-tag: "string": add serialization tags to an object property (see Customizing struct tags)x-nullable: true|false (or equivalently x-is-nullable:true|false): accepts null values (i.e. rendered as a pointer)x-go-type: "string": explicitly reuse an already available go typex-class: "string": give explicit polymorphic class name in discriminatorx-order: number: indicates explicit generation ordering for schemas (e.g. models, properties, allOf, ...)x-omitempty: true|false: force the omitempty modifier in struct json and xml tagsx-go-json-string: true:false: force the string modifier in struct json tagsSwagger types are rendered as follows by go-swagger:
| Swagger type | go type |
|---|---|
string (no format) | string |
boolean | bool |
number | float64 |
number format double | float64 |
number format float | float32 |
integer | int64 |
integer format int64 | int64 |
integer format int32 | int32 |
integer format uint64 | uint64 |
integer format uint32 | uint32 |
file | io.ReadCloser(server) or io.Writer (client) |
string format binary | io.ReadCloseror io.Writer |
string with other formats | corresponding type exported by go-openapi/strfmt |
The file type is exposed as a io.ReadCloser (or io.Writer) interface. The actual implementation in a
runtime server or client is provided by the go-openapi/runtime/File type.
The go-openapi/strfmt packages provides a number of predefined "formats" for JSON string types.
The full list of formats supported by this package is here
Here are the rules that turn something into a pointer.
x-nullable, x-isnullable: explicit override to accept null values (otherwise not accepted by Swagger)allOf a schema with another schema with just x-nullable (or other extensions,
but no new properties) turns the schema into a pointerPrimitive types (number, bool and string) are turned into pointers whenever:
Examples:
definitions:
myInteger:
type: integer
minimum: 0
myString:
type: string
minLength: 0
Yields:
type MyInteger *int64
...
type MyString *string
Notice that the following equivalent does not produce a pointer:
definitions:
myInteger:
type: integer
format: uint64
NOTE: read-only properties are not rendered as pointers.
API developers may use the conversion utilities provided by the go-openapi/swag and go-openapi/strfmt/conv packages
to manipulate pointers more easily.
Known limitations: pointers are used to distinguish in golang a zero value from no value set.
This design comes with some shortcomings:
- it is built around the validation use case. In the general case it is not possible to know if a value has been set to a zero value when the type is not a pointer. In cases where this is important, use the
x-nullableextension- using
nullas a proxy for unset, makes uneasy the explicit use of the JSONnulltype Swagger APIs are not supposed to carrynullvalues.go-swaggergenerated APIs can, using thex-nullableextension, and it is then not possible to distinguish a field explicitly set tonullfrom an unset fieldAn alternate design has been experimented but not released. For those interested in pushing forward this project again, see this pull request
You don't always have to resort to pointers to figure out whether a value is empty.
minLength: 1All produced models implement the Validatable interface.
Exceptions:
file types do not support validation (however generated operations may check the maxLength of a file)any type, rendered as interface{}) do not support validationTherefore, type aliases constructed on either a swagger file or an empty schema does not implement this interface.
Validation errors:
go-openapi/errors/Error type, which supports errors codes and composite errors.Validation stops assessing errors down to the property level and does not continue digging all nested strutures as soon as an error is found.
A definition may create an aliased type like this:
definitions:
myDate:
type: string
format: date
Rendered as:
type MyDate strfmt.Date
Notice that setting x-nullable: true in such an alias will not render the type itself into a pointer, but rather,
all containers of his type will use it as a pointer.
Example:
definitions:
myDate:
type: string
format: date
x-nullable: true
anArrayOfDates:
type: array
items:
$ref: '#/definitions/myDate'
Yields:
type MyDate strfmt.Date
...
type AnArrayOfDates []*MyDate
Realiasing
Given the above definitions, we add:
...
herDate:
$ref: #/definitions/myDate
hisDate:
$ref: #/definitions/herDate
Rendered as (requires go1.9+):
type HerDate = MyDate
type HisDate = HerDate
Additional properties in a JSON object are represented in a go struct by map[string]T.
Examples:
definitions:
extensibleObject:
properties:
prop1:
type: integer
additionalProperties:
type: string
format: date
Is rendered as:
type ExtensibleObject struct {
Prop1 int64
ExtensibleObjectProperties map[string]strfmt.Date
}
If there is no restriction on the additional properties:
definitions:
extensibleObject:
type: object
properties:
prop1:
type: integer
additionalProperties: true
We get:
type ExtensibleObject struct {
Prop1 int64
ExtensibleObjectProperties map[string]interface{}
}
A tuple is rendered as a structure with a property for each element of the tuple.
Example:
definitions:
tuple:
type: array
items:
- type: integer
- type: string
- type: string
format: uuid
Gives:
type Tuple struct {
P0 *int64
P1 *string
P2 *strfmt.UUID
}
If we specify additional items as in:
definitions:
extensibleTuple:
type: array
items:
- type: integer
- type: string
- type: string
format: uuid
additionalItems:
- type: number
Gives:
type ExtensibleTuple struct {
P0 *int64
P1 *string
P2 *strfmt.UUID
ExtensibleTupleItems []float64
}
NOTE: currently the P0, P1, ... names are not customizable.
Polymorphic types are swagger's flavor for inheritance (aka hierarchized composition...).
The use of the discriminator keyword gives a special meaning to allOf compositions.
Whenever the special attribute discriminator is used, this means this object definition is
a base type, to be used to extend other types, or subtypes.
The discriminator property indicates which subtype is used whenever an instance of the base type is found. The discriminator's possible values are the names of the subtypes (no aliasing is supported in Swagger 2.0).
NOTE: the discriminator is a
requiredproperty with"type": "string". No validation attached to this property, saverequired, will be honored, as a discriminator property is implicitly anenumwith all the subtype names found in the spec.
The base type must be a JSON-schema object (it has at least one property, the discriminator).
It may define other properties than the discriminator. Like name in this example.
Example:
Pet:
type: object
discriminator: petType
properties:
name:
type: string
petType:
type: string
required:
- name
- petType
A base type is rendered as an interface, with getter/setter funcs on all attributes.
// Pet pet
// swagger:discriminator Pet petType
type Pet interface {
runtime.Validatable
// name
// Required: true
Name() *string
SetName(*string)
// pet type
// Required: true
PetType() string
SetPetType(string)
}
NOTE: an unexported reference concrete type is also generated, but not currently used by models.
A subtype extends a base type. It is defined by composing the base type with an allOf construct.
All subtypes implement the interface of their base type. So in this examples, all instances of Dog may pretend
to be a Pet.
Example:
Dog:
type: object
description: A representation of a dog
allOf:
- $ref: '#/definitions/Pet'
- properties:
packSize:
type: integer
format: int32
description: the size of the pack the dog is from
default: 0
minimum: 0
required:
- packSize
Yields:
// Dog A representation of a dog
// swagger:model Dog
type Dog struct {
nameField *string
// the size of the pack the dog is from
// Required: true
// Minimum: 0
PackSize *int32 `json:"packSize"`
}
// Name gets the name of this subtype
func (m *Dog) Name() *string {
return m.nameField
}
// SetName sets the name of this subtype
func (m *Dog) SetName(val *string) {
m.nameField = val
}
// PetType gets the pet type of this subtype
func (m *Dog) PetType() string {
return "Dog"
}
// SetPetType sets the pet type of this subtype
func (m *Dog) SetPetType(val string) {
}
Notice the unexported fields which correspond to the description of the base type. The properties of the base type are available with getter/setter functions.
NOTE: if you expand your spec, the
allOfsemantics are lost. Do not expand specs with polymorphic types for code generation.
You may define several such derived types.
Example:
cat:
type: object
description: A representation of a cat
allOf:
- $ref: '#/definitions/Pet'
- properties:
huntingSkill:
type: string
description: The measured skill for hunting
default: lazy
enum:
- clueless
- lazy
- adventurous
- aggressive
required:
- huntingSkill
// Cat A representation of a cat
// swagger:model cat
type Cat struct {
nameField *string
// The measured skill for hunting
// Required: true
// Enum: [clueless lazy adventurous aggressive]
HuntingSkill *string `json:"huntingSkill"`
}
// Name gets the name of this subtype
func (m *Cat) Name() *string {
return m.nameField
}
// SetName sets the name of this subtype
func (m *Cat) SetName(val *string) {
m.nameField = val
}
// PetType gets the pet type of this subtype
func (m *Cat) PetType() string {
return "cat"
}
// SetPetType sets the pet type of this subtype
func (m *Cat) SetPetType(val string) {
}
Notice that the value of the discriminator field is case sensitive, e.g. "Dog" and "cat" above.
Base types and subtypes may be used in other constructs. While subtypes are mostly handled like ordinary objects, there are special provisions taken to generate new types composing base types.
Example:
Kennel:
type: object
required:
- pets
properties:
id:
type: integer
format: int64
pets: # <-- this may contain Cats and Dogs
type: array
items:
$ref: "#/definitions/Pet"
Yields:
// Kennel kennel
// swagger:model Kennel
type Kennel struct {
// id
ID int64 `json:"id,omitempty"`
petsField []Pet
}
// Pets gets the pets of this base type
func (m *Kennel) Pets() []Pet {
return m.petsField
}
// SetPets sets the pets of this base type
func (m *Kennel) SetPets(val []Pet) {
m.petsField = val
}
NOTE: this representation with unexported fields for references to base types might be subject to change in the future, as it is not consistent in all cases. If you are intested to participate this design work, feel free to comment and express your views here.
Subtypes and composed types have custom [un]marshallers.
Unmarshalling a base type is not carried through the standard MarshalJSON()/UnmarshalJSON() pair, but with factories created for each base type.
Example:
// UnmarshalPet unmarshals polymorphic Pet
func UnmarshalPet(reader io.Reader, consumer runtime.Consumer) (Pet, error)
// UnmarshalPetSlice unmarshals polymorphic slices of Pet
func UnmarshalPetSlice(reader io.Reader, consumer runtime.Consumer) ([]Pet, error)
Note that the marshalling of a base type into JSON is processed naturally, so there is no need for a special function.
Known limitations: As of v0.15, there are still some known limitations:
- Unmarshalling maps of base types is not supported at the moment (e.g.
UnmarshalPetMap()factory)- More complex constructs like
[][]Pet,[]map[string]Petare not supported yet- composing tuples containing base types is not supported yet
Tags are generally sufficient to provide proper JSON marshalling capabilities.
Models define some custom [un]marshallers in the following situations:
map[string]...External types refer to custom type definitions, short-circuiting the use of generated models.
This is helpful for use-cases when custom marshaling or validation is needed.
Models may also be generated once, customized manually, then reused in spec as external types.
The extension annotation to declare an external type is x-go-type.
A complete example is provided here to illustrate the different capabilities to inject custom types.
Examples:
External types are typically used in top-level model definitions, like so:
definitions:
myType:
type: object
x-go-type:
type: MyExternalType # <- abide by go conventions! The type must be exported
import:
package: github.com/example/models/custom # <- use fully qualified package names
Such definitions do not produce any generated model.
References in the generated code to this type will produce code like this:
custom.MyExternalType
If no package is provided, it defaults to the models package indicated for codegen:
definitions:
generatedType:
type: array
items:
$ref: '#/definitions/myType'
myType:
type: object
x-go-type:
type: MyExternalType
swagger generate models --model-package custom --target ./codegen
ls ./codegen/custom # <- myType is NOT GENERATED
cat ./codegen/custom/generated_type.go
package custom
type GeneratedType []MyType
External types may also be injected at lower schema levels:
definitions:
MyType:
type: array
items:
type: string
x-go-type:
type: MyExternalString
import:
package: github.com/example/models/custom
or:
MyObject:
type: object
properties:
p1:
x-go-type:
type: RawMessage
import:
package: encoding/json
hints:
kind: interface
This also works for inlined types defined at the operation level:
parameters:
- in: body
name: corpus
schema:
type: object
x-go-type:
type: MyExternalStruct
import:
package: github.com/example/models/custom
NOTE: when defining inline arrays or maps, you should know that the external type is not considered nullable by default.
Therefore, unless you explicitly hint the generator to consider it nullable, you'll get constructs such as
[]external.MyTypeormap[string]external.MyTypeinstead of[]*external.MyTypeandmap[string]*external.MyTyperespectively. You can use thenullablehint or thex-nullableextension to control this behavior.
External types only apply to schema objects. Simple swagger types used in operations for query or path parameters or for response headers cannot be externalized at this moment.
Inlined external types cannot be declared inside polymorphic types (discriminated types).
Inlined external types cannot be declared as embedded. Only top-level definitions are supported.
The following example replaces all references to myModel by github.com/example/models/MyCustomModel.
Example:
definitions:
myModel:
type: object
x-go-type:
type: MyCustomModel
import:
package: github.com/example/models
Note that the external model must implement the github.com/go-openapi/runtime.Validatable interface: it must know how to validate a schema.
No model is generated for this definition.
External packages may be imported with an alias, like so:
parameters:
in: body
schema:
type: object
x-go-type:
type: MyExternalStruct
import:
package: github.com/example/models/custom
alias: fred
Imports will look like so:
import (
fred "github.com/example/models/custom"
)
...
Some deconfliction with other known import is applied automatically. Automatic deconfliction is not perfect, though.
For example:
MyObject:
type: object
properties:
p1:
x-go-type:
type: RawMessage
import:
package: encoding/json
hints:
kind: interface
import (
jsonext "encoding/json"
)
Sometimes, it is impractical to impose the constraint that the external type has a validation method. You can then use the "embedded" option to create an embedded type based on the external model, and wraps the Validate method.
Example:
definitions:
Time:
type: string
format: date-time # <- documentary only (external types takes over). This has no impact on generation.
x-go-type:
type: Time
import:
package: time
embedded: true
This example generates a wrapper type in the package model with a Validate method like this:
import (
timeext "time"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// Time time
//
// swagger:model Time
type Time struct {
timeext.Time
}
func (m Time) Validate(formats strfmt.Registry) error {
var f interface{} = m.Time
if v, ok := f.(runtime.Validatable); ok {
return v.Validate(formats)
}
return nil
}
The generated Validate method uses any existing Validate method or just returns nil (i.e. data is valid).
NOTE: at the moment, we do not support the
formatspecification over the embedded type. Format will be documentary only in that case.
Other examples:
Raw:
x-go-type:
type: RawMessage
import:
package: encoding/json
hints:
kind: primitive
embedded: true
import (
...
jsonext "encoding/json"
...
)
type Raw struct {
jsonext.RawMessage
}
func (m Raw) Validate(formats strfmt.Registry) error {
var f interface{} = m.RawMessage
if v, ok := f.(runtime.Validatable); ok {
return v.Validate(formats)
}
return nil
}
You can embed types as pointers just the same.
Example:
definitions:
Time:
type: string
x-go-type:
type: Time
import:
package: time
hints:
nullable: true # <- nullable here refers to the nullability of the embedded external type
embedded: true
type Time struct {
*time.Time
}
Using external types is powerful, but normally you still have to describe your type in the specification. That is expected, since this is how you document your API.
If you don't (that is the type referred to doesn't correspond to the type in the spec), then the generator may fail to produce correct code, because it simply has no way to infer what kind of object is being referred to.
To solve this kind of problem, you may hint the generator to produce a correct usage of the external types, even though the specification doesn't reflect the correct nature of the object.
Example:
definitions:
Error:
type: object
Hotspot:
x-go-type:
type: Hotspot
import:
package: github.com/go-swagger/go-swagger/fixtures/enhancements/2224/external
hints:
kind: object
x-nullable: true
In this example, the Hotspot schema is empty in the specification. The generator therefore can only guess that this is some interface{} type.
Now thanks to the hint kind: object, we instruct the generator to expect an object so as to correctly reference this object.
By default, the generator assumes that external types can be validated and will generate code that calls the "Validate" method of the type.
This can be disabled by providing an explicit hint:
MyObject:
type: object
properties:
p1:
x-go-type:
type: RawMessage
import:
package: encoding/json
hints:
noValidation: true
External types with an hint type "interface" or "stream" do not call validations.
Embedded types use type assertion to dynamically determine if the external type implements the runtime.Validatable interface.
The generator does not attempt to introspect external types. They may even not exist at generation time.
Therefore, the generator has no idea of whether it is safe to generate pointers to the external type.
By default, external types are considered non nullable. This can be altered with the nullable hint or by hinting a type that is considered nullable (such as "object").
Supported hints:
x-go-type:
type: {external type name (exported symbol, without package qualifier)}
import:
package: {fully qualified package name - defaults to the target models defined by the --model-package flag}
hints:
kind: {map|object|array|interface|primitive|tuple|stream}
noValidation: true|false # <- skips validation: defaults to true for embedded types, defaults to false for non-embedded, always false for kinds interface and stream
nullable: true|false # <- default to true for kinds object,primitive and tuple
embedded: true|false # <- defaults to false, generates a struct that wraps the external type
At this moment, external packages and aliases are deconflicted against other known imports and variables.
Example:
MyObject:
type: object
properties:
p1:
x-go-type:
type: RawMessage
import:
package: encoding/json
hints:
kind: interface
will generate an import deconflicted against the standard lib import:
import(
...
jsonext "encoding/json"
...
)
External packages may be imported with an alias, like so:
parameters:
in: body
schema:
type: object
x-go-type:
type: MyExternalStruct
import:
package: github.com/example/models/custom
alias: fred
Imports will look like so:
import (
fred "github.com/example/models/custom"
)
...
Some deconfliction with other known imports is applied automatically. Automatic deconfliction is not perfect, though.
For example:
MyObject:
type: object
properties:
p1:
x-go-type:
type: RawMessage
import:
package: encoding/json
hints:
kind: interface
import (
jsonext "encoding/json"
)
Package aliases may still conflict with packages produces by operation tags or other external imports.
In such cases, modify the type alias under x-go-type to resolve the conflict manually.
When a model struct is generated, tags for json are generated to keep the original name:
type ObjectWithTag struct {
StandardTag string `json:"standardTag,omitempty"`
}
Extra tags may be defined with the CLI generation option --sruct-tags.
Extra tags essentially repeat the name of the field can be added from the command line option.
NOTE: at this moment, all tag modifiers (omitempty, string) are repeated like for the json tag.
swagger generate model ... --struct-tags yaml,db
type ObjectWithTag struct {
StandardTag string `json:"standardTag,omitempty" yaml:"standardTag,omitempty" db:"standardTag,omitempty"`
}
A custom may be added to a field using the x-go-custom-tag extension. Like so:
By default, a struct field is omitted when it holds the zero value (tag modifier: omitempty).
Required fields are never omitted.
type ObjectWithTag struct {
RequiredField *string `json:"requiredField"`
}
This property can be altered using the x-omitempty extension. Like so:
objectWithTag:
type: object
properties:
field:
type: string
x-omitempty: false
type ObjectWithTag struct {
Field string `json:"field"`
}
The extension does not force a required field to get the "omitempty" modifier.
For some specific requirements, the standard json library may consider numbers as strings.
This is done by adding the modifier json:"...,string" to the tag.
With go-swagger you can specify this modifier by adding the x-go-json-string: true extension to your type.
type ObjectWithTag struct {
NumericField int `json:"field,omitempty,string"`
}
The XML name and attribute Swagger properties are used to generate extra tags.
definitions:
objectWithXML:
type: object
properties:
field:
type: string
xml:
name: xmlObject
attribute: true
type ObjectWithXML struct {
Field string `json:"field,omitempty" xml:"xmlObject,attr,omitempty"`
}
If you add example to the list of generated tags from the CLI (swagger generate ... --struct-tags example),
a special example tag is created with the example value taken from the specification.
definitions:
objectWithExample:
properties:
field:
type: string
example: "sample"
type ObjectWithExample struct {
Field string `json:"field,omitempty" example:"\"sample\""`
}
If you add description to the list of generated tags from the CLI (swagger generate ... --struct-tags description),
a special description tag is created with the description value taken from the specification.
definitions:
objectWithDescription:
properties:
field:
type: string
description: "some description"
type ObjectWithDescription struct {
Field string `json:"field,omitempty" description:"\"some description\""`
}