github.com/kaisawind/go-swagger@v0.19.0/docs/use/models/schemas.md (about)

     1  # Schema generation rules
     2  
     3  Lots of the work carried out by go-swagger is to generate models, which can have all kinds of rules like polymorphism and
     4  validations.  Go-swagger models are the go data structures used for serialization and validation.
     5  
     6  Of course none of this is possible without a set of rules and trade offs.
     7  
     8  ### About schemas
     9  
    10  A schema is a data structure specified in a Swagger document. Loosely speaking, a swagger schema corresponds to
    11  a JSONSchema-draft4 schema (see [differences](#swagger-vs-jsonschema) below).
    12  For each schema, `go-swagger` will generate one or more model types in go.
    13  
    14  > **NOTE**: Swagger makes a distinction between schemas and "simple schemas".
    15  > We use simple schemas to describe parameters and headers for operations.
    16  > Simple schemas are supported by `go-swagger` (including validation), but are not rendered as standalone models.
    17  > Rather, simple schema structures and validation methods are generated with the operation they are attached to.
    18  >
    19  > Models are dedicated to the description of Swagger schemas, which are described as a parameter body, a response or a
    20  > spec definition.
    21  
    22  #### Interfaces
    23  
    24  The generated models implements:
    25  
    26  - a serialization interface
    27    - `MarshalJSON()`, `UnmarshalJSON()`:
    28      - standard structures use JSON decoder tags (serialization tags are customizable)
    29      - composed and extensible structures use custom marshalers (`allOf`, `additionalProperties`, tuples and polymorphic types)
    30    - `MarshalBinary()`, `UnmarshalBinary()` interfaces (`encoding/BinaryMarshaler`, `encoding/BinaryUnmarshaler`),
    31   which may use the fast [`mailru/easyjson`][easy-json] package
    32  - a validation interface ([`go-openapi/runtime/Validatable`][Validatable]), with a `Validate(strfmt.Registry) error` method
    33  
    34  Validation methods are wired at generation time, and rely mostly on native types: this makes validation faster than a
    35  dynamic general purpose JSON schema validator.
    36  
    37  Example of a generated structure:
    38  ```golang
    39  // Principal principal
    40  // swagger:model principal
    41  type Principal struct {
    42  
    43  	// name
    44  	Name string `json:"name,omitempty"`
    45  
    46  	// roles
    47  	Roles []string `json:"roles"`
    48  }
    49  ```
    50  
    51  > **NOTE**: if you are looking for a **dynamic**, fully JSONSchema compliant, general purpose validator,
    52  > the [`go-openapi/validate`][validate] package
    53  > is what you want. It is fully tested against the JSONSchema-Test-Suite (supports JSON-schema-draft4).
    54  > See a working example [here][validate-json].
    55  
    56  #### Mapping patterns
    57  
    58  The general idea is that you should rarely see `interface{}` in the generated code:
    59  you get a complete representation of a swagger document in somewhat idiomatic go.
    60  
    61  There is set of mapping patterns that are applied to transform a spec into go types:
    62  
    63  * definition of primitive => type alias/name
    64  * definition of array => type alias/name
    65  * definition of map => type alias/name
    66  * definition of object with properties => struct
    67  * definition of $ref => type alias/name
    68  * object with only additional properties => map[string]T
    69  * object with additional properties and properties => custom serializer
    70  * schema with schema array in items => tuple (struct with properties, custom serializer)
    71  * schema with all of => struct
    72  * all of schema with ref => embedded value
    73  * all of schema with properties => properties are included in struct
    74  * adding an all of schema with just `x-isnullable`: true or `x-nullable`: true turns
    75  the schema into a pointer when there are only other extension properties provided
    76  * additional items in tuples =>
    77  JSONSchema and by extension swagger allow for items that have a fixed size array
    78  with schema's describing the items at each index. This can be combined with additional items
    79  to form some kind of tuple with varargs.
    80  To map this to go it creates a struct that has fixed names and a custom json serializer.
    81  
    82  #### Minimal use of go's reflection
    83  
    84  Generated models uses _no reflection_ except for `enum` and `required` validations. This makes validation faster.
    85  
    86  #### Doc strings
    87  
    88  All documentation items provided by the spec are integrated as godoc-friendly comments in the
    89  generated source. You may look at how a trivial example is rendered [here][go-doc-model].
    90  
    91  The code that is generated also gets the same doc comments that are used by the scanner
    92  to generate a spec from go code (e.g. comments like `// swagger:xxx`).
    93  So that after generation you should be able to reverse-generate a spec from the code that was generated by your spec.
    94  It should be equivalent to the original spec but might miss some default values and examples.
    95  
    96  #### Types reusability
    97  
    98  Models can be generated independently from other components of your API.
    99  Internal model structures may thus be safely regenerated if the contract at your endpoints does not change.
   100  
   101  Previously generated models can be reused when constructing a new API server or client (e.g. using `swagger generate server --model=[my existing package]`).
   102  
   103  The generator makes every effort to keep the go code readable, idiomatic and commented: models may thus be manually customized or extended.
   104  Such customized types may be later on reused in other specs, using the `x-go-type` extension.
   105  
   106  ### Swagger vs JSONSchema
   107  
   108  A Swagger 2.0 schema corresponds by and large to a JSON-schema-draft4. However, there are some substantial differences (see [swagger]):
   109  
   110  In JSONSchema, but _not_ in Swagger 2.0:
   111  
   112  - `anyOf`, `oneOf` and `not` constructs are not supported (this is for OpenAPI 3)
   113  - the `null` type is not supported (the `nullable` keyword is defined in OpenAPI 3)
   114  - `additionalItems` are not supported (go-swagger does support it)
   115  - `patternProperties` are not supported
   116  - `dependencies` are not supported
   117  - multiple types, defined as `type: [ ... ]` are not supported
   118  
   119  Conversely, what we have in Swagger 2.0, but _not_ in JSON-schema:
   120  
   121  - the `discriminator` attribute controls polymorphism ([see below](#polymorphic-types))
   122  - properties may be given a [`readOnly` attribute][read-only] (same as in JSONSchema-draft7)
   123  - `array` types **must** have an `items` restriction
   124  - `format` supports more values for strings and numbers
   125  
   126  Other minor differences:
   127  
   128  - `default` values **must** validate their schema
   129  - types `array` **must** have an `items` specification
   130  - extensions may be specified as special `x-...` annotations. Go-swagger defines [some custom tags](#custom-extensions) to customize generated code.
   131  - other available attributes: `example`, `xml` and `externalDocs`
   132  
   133  > **NOTE**: `example` and `externalDocs` do not currently influence models generation.
   134  
   135  ### Go-swagger vs Swagger
   136  
   137  go-swagger models implements _almost_ all Swagger 2.0 schema features.
   138  
   139  We also wanted to support as much JSONSchema features as possible: the model generator may be used independently
   140  to generate data structure using the Swagger specification as a serialization description language.
   141  
   142  There are some small differences or implementation details to be aware of.
   143  
   144  |   Feature                             | JSON-schema-draft4 |  Swagger 2.0 |  go-swagger |   Comment | 
   145  |---                                    |---                 |---           |---          |---        |
   146  | `"format"`                            |   Y| Y    | Y      | Formats are provided by the extensible [`go-openapi/strfmt` package][strfmt]. See also [here](#formatted-types)|
   147  | `"additionalProperties": {schema}`    |   Y| Y    | Y      | Rendered as `map[string]T`                           |
   148  | `"additionalProperties": boolean`     |   Y| Y    | partial| Rendered as `map[string]interface{}`                           |
   149  | `"additionalItems": {schema}`         |   Y| **N**| Y      | Rendered with [tuple models](#tuples-and-additional-items)|
   150  | `"additionalItems": boolean`          |   Y| **N**| partial| See [extensible types](#extensible-types)             |
   151  | empty object: `{ "type": "object"}`   |   Y| Y    | Y      | Rendered as `interface{}` (anything) rather than `map[string]inferface{}` (any JSON object, e.g. not arrays)|
   152  | `"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)|
   153  |  large number, arbitrary precision    |   Y| **N**| N      |    |
   154  | `"readOnly"`                          |   N| Y    | N      | `readOnly` is currently not supported by the model validation method |
   155  | `"type": [ "object", ... ]`           |   Y| N    | N      | JSONSchema multiple types are not supported: use Swagger polymorphism instead|
   156  | 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|
   157  | tuple `type: "array" items:[...]      |   Y| Y    | partial| As of v0.15, incomplete tuples and tuples with array validation are not properly validated|
   158  
   159  
   160  JSONSchema defaults to `"additionalProperties": true`, `go-swagger` defaults to ignoring this. Same for `additionalItems`.
   161  
   162  When`"additionalProperties": false` (resp. `"additionalItems": false`), uwanted properties (resp. items) do not invalidate data
   163  but they are not kept in the model.
   164  
   165  This is the default if `additionalProperties` (resp. `additionalItems`) is not provided.
   166  It is an optimization as it makes the code simpler (and faster) for most use cases.
   167  Explicitly specifying `true` will produce models that retain those additional properties (resp. items).
   168  
   169  ### Known limitations with go-swagger models
   170  
   171  Recap as of release `0.15`:
   172  
   173  - re [Swagger 2.0 specification][swagger]
   174  
   175    - no validation support for the `readOnly` attribute
   176   
   177  - re [JSON-schema-draft4][json-schema]
   178  
   179    - `"additionalProperties": false`, `"additionalItems": false` do not invalidate data with extra properties. We trade strictness for speed and
   180    truncate unwanted properties or items without further validation.
   181    - when `enum` values cannot be marshalled into their schema, a runtime panic occurs - the `go-openapi/validate` package does not yet detect this situation
   182    - `minProperties`, `maxProperties` are not supported
   183    - `patternProperties` and `dependencies`are not supported
   184    - use of `additionalItems` requires the `--skip-validation` flag (`go-openapi/validate` is strict regarding Swagger specification)
   185    - JSONSchema defaults to the `"additionalProperties": true`, `go-swagger` defaults to ignore this. Same for `additionalItems`.
   186    - use of `additionalItems` requires the `--skip-validation` flag (`go-openapi/validate` is strict regarding Swagger specification)
   187    - array validations (`minItems`, etc.) are not yet supported for tuples, as of v0.15
   188    - objects with no properties and no additional properties schema have no validation at all (e.g. passing an array is not invalid) (rendered as `interface{}`)
   189    - `null` JSON type: the `null` type is not supported by Swagger - use of the `x-nullable` extension makes `null` values valid
   190    (notice that combining the use of `required` and `x-nullable` is not fully JSONSchema compliant - see [below](#nullability))
   191  
   192  ### Custom extensions
   193  
   194  Model generation may be altered with the following extensions:
   195  
   196  - `x-go-name: "string"`: give explicit type name to the generated model 
   197  - `x-go-custom-tag: "string"`: add serialization tags to an object property
   198  - `x-nullable: true|false` (or equivalently `x-is-nullable:true|false`): accepts null values (i.e. rendered as a pointer)
   199  - `x-go-type: "string"`: explicitly reuse an already available go type
   200  - `x-class: "string"`: give explicit polymorphic class name in discriminator
   201  - `x-order: number`: indicates explicit generation ordering for schemas (e.g. models, properties, allOf, ...)
   202  
   203  ### Primitive types
   204  
   205  Swagger types are rendered as follows by `go-swagger`:
   206  
   207  | Swagger type                | go type  |
   208  |-----------------------------|----------|
   209  | `string` (no format)        | `string` |
   210  | `boolean`                   | `bool`   |
   211  | `number`                    | `float64`|
   212  | `number format double`      | `float64`|
   213  | `number format float`       | `float32`|
   214  | `integer`                   | `int64`  |
   215  | `integer format int64`      | `int64`  |
   216  | `integer format int32`      | `int32`  |
   217  | `integer format uint64`     | `uint64` |
   218  | `integer format uint32`     | `uint32` |
   219  | `file`                      | `io.ReadCloser`(server) or `io.Writer` (client)|
   220  | `string format binary`      | `io.ReadCloser`or `io.Writer`|
   221  | `string` with other formats | corresponding type exported by `go-openapi/strfmt` |
   222  
   223  The `file` type is exposed as a `io.ReadCloser` (or `io.Writer`) interface. The actual implementation in a
   224  runtime server or client is provided by the [`go-openapi/runtime/File` type][File].
   225  
   226  ### Formatted types
   227  
   228  The `go-openapi/strfmt` packages provides a number of predefined "formats" for JSON string types.
   229  The full list of formats supported by this package is [here][all-formats]
   230  
   231  ### Nullability
   232  
   233  Here are the rules that turn something into a pointer.
   234  * structs
   235  * `x-nullable`, `x-isnullable`: explicit override to accept null values (otherwise not accepted by Swagger)
   236  * required property
   237  * extending with `allOf` a schema with another schema with just `x-nullable` (or other extensions,
   238  but no new properties) turns the schema into a pointer
   239  
   240  Primitive types (number, bool and string) are turned into pointers whenever:
   241  * we need to validate valid zero values vs unset (i.e. the zero value is explicitly checked against validation)
   242  
   243  Examples:
   244  ```yaml
   245  definitions:
   246    myInteger:
   247      type: integer
   248      minimum: 0
   249    myString:
   250      type: string
   251      minLength: 0
   252  ```
   253  
   254  Yields:
   255  ```go
   256  type MyInteger *int64
   257  ...
   258  type MyString *string
   259  ```
   260  
   261  Notice that the following equivalent does not produce a pointer:
   262  ```yaml
   263  definitions:
   264    myInteger:
   265      type: integer
   266      format: uint64
   267  ```
   268  
   269  > NOTE: read-only properties are not rendered as pointers.
   270  
   271  API developers may use the converter utilities provided by the `go-openapi/swag` and `go-openapi/strfmt/conv` packages
   272  to manipulate pointers more easily.
   273  
   274  > **Known limitations**:
   275  > pointers are used to distinguish in golang a zero value from no value set.
   276  >
   277  > This design comes with some shortcomings:
   278  >
   279  > - it is built around the validation use case.
   280  > In the general case it is not possible to know if a value has been set
   281  > to a zero value when the type is not a pointer. In cases where this is
   282  > important, use the `x-nullable` extension
   283  > - using `null` as a proxy for unset, makes uneasy the explicit use of the JSON `null` type
   284  > Swagger APIs are not supposed to carry `null` values. 
   285  > `go-swagger` generated APIs can, using the `x-nullable` extension, and it is then not possible
   286  > to distinguish a field explicitly set to `null` from an unset field
   287  >
   288  > An alternate design has been experimented but not released. For those interested in pushing forward this project again,
   289  > see [this pull request][lifting-pointers]
   290  
   291  
   292  ### Validation
   293  All produced models implement the [Validatable] interface.
   294  
   295  Exceptions:
   296  - `file` types do not support validation (however generated operations may check the `maxLength` of a file)
   297  - empty schemas (`any` type, rendered as `interface{}`) do not support validation
   298  
   299  Therefore, type aliases constructed on either a swagger `file` or an empty schema does not implement this interface.
   300  
   301  Validation errors:
   302  - Returned errors are supported by the `go-openapi/errors/Error` type, which supports errors codes and composite errors.
   303  
   304  Validation stops assessing errors down to the property level and does not continue digging all nested strutures as soon
   305  as an error is found.
   306  
   307  ### Type aliasing
   308  
   309  A definition may create an _aliased_ type like this:
   310  
   311  ```yaml
   312  definitions:
   313    myDate:
   314      type: string
   315      format: date
   316  ```
   317  
   318  Rendered as:
   319  ```go
   320  type MyDate strfmt.Date
   321  ```
   322  
   323  Notice that setting `x-nullable: true` in such an alias will not render the type itself into a pointer, but rather,
   324  all containers of his type will use it as a pointer.
   325  
   326  Example:
   327  ```yaml
   328  definitions:
   329    myDate:
   330      type: string
   331      format: date
   332      x-nullable: true
   333    anArrayOfDates:
   334      type: array
   335      items:
   336        $ref: '#/definitions/myDate'
   337  ```
   338  
   339  Yields:
   340  ```go
   341  type MyDate strfmt.Date
   342  ...
   343  type AnArrayOfDates []*MyDate
   344  ```
   345  
   346  Realiasing
   347  
   348  Given the above definitions, we add:
   349  
   350  ```yaml
   351    ...
   352    herDate:
   353      $ref: #/definitions/myDate
   354    hisDate:
   355      $ref: #/definitions/herDate
   356  ```
   357  
   358  Rendered as (requires go1.9+):
   359  ```go
   360  type HerDate = MyDate
   361  ```
   362  
   363  ```go
   364  type HisDate = HerDate
   365  ```
   366  
   367  ### Extensible types
   368  
   369  ##### Objects and additional properties
   370  
   371  Additional properties in a JSON object are represented in a go struct by `map[string]T`.
   372  
   373  Examples:
   374  
   375  ```yaml
   376  definitions:
   377    extensibleObject:
   378      properties:
   379        prop1:
   380          type:  integer
   381      additionalProperties:
   382        type: string
   383        format: date
   384  ```
   385  
   386  Is rendered as:
   387  ```golang
   388  type ExtensibleObject struct {
   389      Prop1 int64
   390      ExtensibleObjectProperties map[string]strfmt.Date
   391  }
   392  ```
   393  
   394  If there is no restriction on the additional properties:
   395  
   396  ```yaml
   397  definitions:
   398    extensibleObject:
   399      type: object
   400      properties:
   401        prop1:
   402          type: integer
   403      additionalProperties: true
   404  ```
   405  
   406  We get:
   407  ```golang
   408  type ExtensibleObject struct {
   409      Prop1 int64
   410      ExtensibleObjectProperties map[string]interface{}
   411  }
   412  ```
   413  
   414  ##### Tuples and additional items
   415  
   416  A tuple is rendered as a structure with a property for each element of the tuple.
   417  
   418  Example:
   419  ```yaml
   420  definitions:
   421    tuple:
   422      type: array
   423      items:
   424      - type: integer
   425      - type: string
   426      - type: string
   427        format: uuid
   428  ```
   429  
   430  Gives:
   431  ```golang
   432  type Tuple struct {
   433      P0 *int64
   434      P1 *string
   435      P2 *strfmt.UUID
   436  }
   437  ```
   438  
   439  If we specify additional items as in:
   440  ```yaml
   441  definitions:
   442    extensibleTuple:
   443      type: array
   444      items:
   445      - type: integer
   446      - type: string
   447      - type: string
   448        format: uuid
   449      additionalItems:
   450      - type: number
   451  ```
   452  Gives:
   453  ```golang
   454  type ExtensibleTuple struct {
   455      P0 *int64
   456      P1 *string
   457      P2 *strfmt.UUID
   458      ExtensibleTupleItems []float64
   459  }
   460  ```
   461  
   462  > **NOTE**: currently the P0, P1, ... names are not customizable.
   463  
   464  ### Polymorphic types
   465  
   466  Polymorphic types are swagger's flavor for inheritance (aka _hierarchized composition_...).
   467  The use of the `discriminator` keyword gives a special meaning to `allOf` compositions.
   468  
   469  #### Base types
   470  Whenever the special attribute `discriminator` is used, this means this object definition is
   471  a base type, to be used to extend other types, or subtypes.
   472  
   473  The discriminator property indicates which subtype is used whenever an instance of the base type is found.
   474  The discriminator's possible values are the names of the subtypes (no aliasing is supported in Swagger 2.0).
   475  
   476  > **NOTE**: the discriminator is a `required` property with `"type": "string"`.
   477  > No validation attached to this property, save `required`, will be honored, as
   478  > a discriminator property is implicitly an `enum` with all the subtype names found in the spec.
   479  
   480  The base type must be a JSON-schema object (it has at least one property, the discriminator).
   481  It may define other properties than the discriminator. Like `name` in this example.
   482  
   483  Example:
   484  ```yaml
   485    Pet:
   486      type: object
   487      discriminator: petType
   488      properties:
   489        name:
   490          type: string
   491        petType:
   492          type: string
   493      required:
   494      - name
   495      - petType
   496  ```
   497  
   498  A base type is rendered as an interface, with getter/setter funcs on all attributes.
   499  
   500  ```go
   501  // Pet pet
   502  // swagger:discriminator Pet petType
   503  type Pet interface {
   504  	runtime.Validatable
   505  
   506  	// name
   507  	// Required: true
   508  	Name() *string
   509  	SetName(*string)
   510  
   511  	// pet type
   512  	// Required: true
   513  	PetType() string
   514  	SetPetType(string)
   515  }
   516  ```
   517  
   518  > **NOTE**: an unexported reference concrete type is also generated, but not currently used by models.
   519  
   520  #### Subtypes
   521  
   522  A subtype _extends_ a base type. It is defined by composing the base type with an `allOf` construct.
   523  All subtypes implement the interface of their base type. So in this examples, all instances of `Dog` may pretend
   524  to be a `Pet`.
   525  
   526  Example:
   527  ```yaml
   528    Dog:
   529      type: object
   530      description: A representation of a dog
   531      allOf:
   532      - $ref: '#/definitions/Pet'
   533      - properties:
   534          packSize:
   535            type: integer
   536            format: int32
   537            description: the size of the pack the dog is from
   538            default: 0
   539            minimum: 0
   540        required:
   541        - packSize
   542  ```
   543  
   544  Yields:
   545  ```go
   546  // Dog A representation of a dog
   547  // swagger:model Dog
   548  type Dog struct {
   549  	nameField *string
   550  
   551  	// the size of the pack the dog is from
   552  	// Required: true
   553  	// Minimum: 0
   554  	PackSize *int32 `json:"packSize"`
   555  }
   556  
   557  // Name gets the name of this subtype
   558  func (m *Dog) Name() *string {
   559  	return m.nameField
   560  }
   561  
   562  // SetName sets the name of this subtype
   563  func (m *Dog) SetName(val *string) {
   564  	m.nameField = val
   565  }
   566  
   567  // PetType gets the pet type of this subtype
   568  func (m *Dog) PetType() string {
   569  	return "Dog"
   570  }
   571  
   572  // SetPetType sets the pet type of this subtype
   573  func (m *Dog) SetPetType(val string) {
   574  
   575  }
   576  ```
   577  
   578  Notice the unexported fields which correspond to the description of the base type.
   579  The properties of the base type are available with getter/setter functions.
   580  
   581  > **NOTE**: if you expand your spec, the `allOf` semantics are lost.
   582  > Do not expand specs with polymorphic types for code generation.
   583  
   584  You may define several such derived types.
   585  
   586  Example:
   587  ```yaml
   588    cat:
   589      type: object
   590      description: A representation of a cat
   591      allOf:
   592      - $ref: '#/definitions/Pet'
   593      - properties:
   594          huntingSkill:
   595            type: string
   596            description: The measured skill for hunting
   597            default: lazy
   598            enum:
   599            - clueless
   600            - lazy
   601            - adventurous
   602            - aggressive
   603        required:
   604        - huntingSkill
   605  ```
   606  
   607  ```go
   608  // Cat A representation of a cat
   609  // swagger:model cat
   610  type Cat struct {
   611  	nameField *string
   612  
   613  	// The measured skill for hunting
   614  	// Required: true
   615  	// Enum: [clueless lazy adventurous aggressive]
   616  	HuntingSkill *string `json:"huntingSkill"`
   617  }
   618  
   619  // Name gets the name of this subtype
   620  func (m *Cat) Name() *string {
   621  	return m.nameField
   622  }
   623  
   624  // SetName sets the name of this subtype
   625  func (m *Cat) SetName(val *string) {
   626  	m.nameField = val
   627  }
   628  
   629  // PetType gets the pet type of this subtype
   630  func (m *Cat) PetType() string {
   631  	return "cat"
   632  }
   633  
   634  // SetPetType sets the pet type of this subtype
   635  func (m *Cat) SetPetType(val string) {
   636  
   637  }
   638  ```
   639  
   640  Notice that the value of the discriminator field is case sensitive, e.g. `"Dog"` and `"cat"` above.
   641  
   642  #### Type composition
   643  
   644  Base types and subtypes may be used in other constructs. While subtypes are mostly handled like ordinary objects,
   645  there are special provisions taken to generate new types composing base types.
   646  
   647  Example:
   648  ```yaml
   649    Kennel:
   650      type: object
   651      required:
   652        - pets
   653      properties:
   654        id:
   655          type: integer
   656          format: int64
   657        pets:          # <-- this may contain Cats and Dogs
   658          type: array
   659          items:
   660            $ref: "#/definitions/Pet"
   661  ```
   662  
   663  Yields:
   664  ```go
   665  // Kennel kennel
   666  // swagger:model Kennel
   667  type Kennel struct {
   668  
   669  	// id
   670  	ID int64 `json:"id,omitempty"`
   671  
   672  	petsField []Pet
   673  }
   674  
   675  // Pets gets the pets of this base type
   676  func (m *Kennel) Pets() []Pet {
   677  	return m.petsField
   678  }
   679  
   680  // SetPets sets the pets of this base type
   681  func (m *Kennel) SetPets(val []Pet) {
   682  	m.petsField = val
   683  }
   684  ```
   685  
   686  > **NOTE**: this representation with unexported fields for references to base types might be subject to change in
   687  > the future, as it is not consistent in all cases. If you are intested to participate this design work,
   688  > feel free to comment and express your views [here](https://github.com/go-swagger/go-swagger/issues/232).
   689  
   690  #### Factories for base types
   691  
   692  Subtypes and composed types have custom [un]marshallers.
   693  
   694  Unmarshalling a base type is not carried through the standard MarshalJSON()/UnmarshalJSON() pair, but with
   695  factories created for each base type.
   696  
   697  Example:
   698  ```go
   699  // UnmarshalPet unmarshals polymorphic Pet
   700  func UnmarshalPet(reader io.Reader, consumer runtime.Consumer) (Pet, error)
   701  
   702  // UnmarshalPetSlice unmarshals polymorphic slices of Pet
   703  func UnmarshalPetSlice(reader io.Reader, consumer runtime.Consumer) ([]Pet, error)
   704  ```
   705  
   706  Note that the marshalling of a base type into JSON is processed naturally, so there is no need for a special function.
   707  
   708  > **Known limitations**:
   709  > As of v0.15, there are still some known limitations:
   710  >
   711  > - Unmarshalling maps of base types is not supported at the moment (e.g. `UnmarshalPetMap()` factory)
   712  > - More complex constructs like `[][]Pet`, `[]map[string]Pet` are not supported yet
   713  > - composing tuples containing base types is not supported yet
   714  
   715  ### Serialization interfaces
   716  
   717  <!--
   718  
   719  TODO
   720  
   721  ##### Serializer's tags
   722  
   723  ##### Custom tags
   724  
   725  JSON
   726  
   727  XML
   728  -->
   729  
   730  ##### Custom serializers
   731  
   732  Tags are generally sufficient to provide proper JSON marshalling capabilities.
   733  
   734  Models define some custom [un]marshallers in the following situations:
   735  - tuples: array elements are dispatched in the tuple's struct
   736  - additionalProperties: additional content is dispatched in the `map[string]...`
   737  - subtypes of base types
   738  - types composed of base types
   739  - aliases on formatted types when the underlying type is not string (e.g. Date, Datetime)
   740  
   741  <!--
   742  ##### [Un]MarshalBinary interfaces
   743  
   744  TODO
   745  -->
   746  
   747  <!-- References -->
   748  
   749  [swagger]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schema-object
   750  [strfmt]: https://github.com/go-openapi/strfmt
   751  [runtime]: https://github.com/go-openapi/runtime
   752  [File]: https://github.com/go-openapi/runtime/blob/master/file.go#L20
   753  [Validatable]: https://github.com/go-openapi/runtime/blob/master/interfaces.go#L101
   754  [validate]: https://github.com/go-openapi/validate
   755  [validate-json]: https://godoc.org/github.com/go-openapi/validate#ex-AgainstSchema
   756  [go-doc-model]: https://godoc.org/github.com/go-swagger/go-swagger/examples/generated/models
   757  [read-only]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields-13
   758  [all-formats]:  https://github.com/go-openapi/strfmt/blob/master/README.md
   759  [easy-json]: https://github.com/mailru/easyjson
   760  [json-schema]: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
   761  [lifting-pointers]: https://github.com/go-swagger/go-swagger/pull/557