# Schema generation rules

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.

### About schemas

A schema is a data structure specified in a Swagger document. Loosely speaking, a swagger schema corresponds to
a JSONSchema-draft4 schema (see [differences](#swagger-vs-jsonschema) 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.

#### Interfaces

The generated models implements:

- a serialization interface
  - `MarshalJSON()`, `UnmarshalJSON()`:
    - standard structures use JSON decoder tags (serialization tags are customizable)
    - composed and extensible structures use custom marshalers (`allOf`, `additionalProperties`, tuples and polymorphic types)
  - `MarshalBinary()`, `UnmarshalBinary()` interfaces (`encoding/BinaryMarshaler`, `encoding/BinaryUnmarshaler`),
  which may use the fast [`mailru/easyjson`][easy-json] package
- a validation interface ([`go-openapi/runtime/Validatable`][Validatable]), with a `Validate(strfmt.Registry) error` method

Validation 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:
```golang
// 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/validate`][validate] package
> is what you want. It is fully tested against the JSONSchema-Test-Suite (supports JSON-schema-draft4).
> See a working example [here][validate-json].

#### Mapping patterns

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:

* definition of primitive => type alias/name
* definition of array => type alias/name
* definition of map => type alias/name
* definition of object with properties => struct
* definition of $ref => type alias/name
* object with only additional properties => map[string]T
* object with additional properties and properties => custom serializer
* schema with schema array in items => tuple (struct with properties, custom serializer)
* schema with all of => struct
* all of schema with ref => embedded value
* all of schema with properties => properties are included in struct
* adding an all of schema with just `x-isnullable`: true or `x-nullable`: true turns
the schema into a pointer when there are only other extension properties provided
* additional items in tuples =>
JSONSchema and by extension swagger allow for items that have a fixed size array
with schema's describing the items at each index. This can be combined with additional items
to form some kind of tuple with varargs.
To map this to go it creates a struct that has fixed names and a custom json serializer.

#### Minimal use of go's reflection

Generated models uses _no reflection_ except for `enum` and `required` validations. This makes validation faster.

#### Doc strings

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][go-doc-model].

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.

#### Types reusability

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.

##### Reusing previous generations

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.


### Swagger vs JSONSchema

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)
- the `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 supported
- `dependencies` are not supported
- multiple types, defined as `type: [ ... ]` are not supported

Conversely, what we have in Swagger 2.0, but _not_ in JSON-schema:

- the `discriminator` attribute controls polymorphism ([see below](#polymorphic-types))
- properties may be given a [`readOnly` attribute][read-only] (same as in JSONSchema-draft7)
- `array` types **must** have an `items` restriction
- `format` supports more values for strings and numbers

Other minor differences:

- `default` values **must** validate their schema
- types `array` **must** have an `items` specification
- extensions may be specified as special `x-...` annotations. Go-swagger defines [some custom tags](#custom-extensions) to customize generated code.
- other available attributes: `example`, `xml` and `externalDocs`

> **NOTE**: `example` and `externalDocs` do not currently influence models generation.

### Go-swagger vs Swagger

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][strfmt]. See also [here](#formatted-types)|
| `"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](#tuples-and-additional-items)|
| `"additionalItems": boolean`          |   Y| **N**| partial| See [extensible types](#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).

### Known limitations with go-swagger models

Recap as of release `>0.26`:

- re [JSON-schema-draft4][json-schema]

  - `"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.
  - the generation flag `--strict-additional-properties` invalidates data with extra properties when `"additionalProperties": false`
  - when `enum` values cannot be marshalled into their schema, a runtime panic occurs - the `go-openapi/validate` package does not yet detect this situation
  - `patternProperties` and `dependencies`are not supported
  - use of `additionalItems` requires the `--skip-validation` flag (`go-openapi/validate` is strict regarding Swagger specification)
  - JSONSchema defaults to the `"additionalProperties": true`, `go-swagger` defaults to ignoring extra properties. Same for `additionalItems`.
  - array validations (`minItems`, etc.) are not yet supported for tuples, as of v0.15
  - 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{}`)
  - `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](#nullability))

### Custom extensions

Model generation may be altered with the following extensions:

- `x-go-name: "string"`: give explicit type name to the generated model
- `x-go-custom-tag: "string"`: add serialization tags to an object property (see [Customizing struct tags](#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 type
- `x-class: "string"`: give explicit polymorphic class name in discriminator
- `x-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 tags
- `x-go-json-string: true:false`: force the string modifier in struct json tags

### Primitive types

Swagger 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.ReadCloser`or `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][File].

### Formatted types

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][all-formats]

### Nullability

Here are the rules that turn something into a pointer.
* structs
* `x-nullable`, `x-isnullable`: explicit override to accept null values (otherwise not accepted by Swagger)
* required property
* extending with `allOf` a schema with another schema with just `x-nullable` (or other extensions,
but no new properties) turns the schema into a pointer

Primitive types (number, bool and string) are turned into pointers whenever:
* we need to validate valid zero values vs unset (i.e. the zero value is explicitly checked against validation)

Examples:
```yaml
definitions:
  myInteger:
    type: integer
    minimum: 0
  myString:
    type: string
    minLength: 0
```

Yields:
```go
type MyInteger *int64
...
type MyString *string
```

Notice that the following equivalent does not produce a pointer:
```yaml
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-nullable` extension
> - using `null` as a proxy for unset, makes uneasy the explicit use of the JSON `null` type
> Swagger APIs are not supposed to carry `null` values.
> `go-swagger` generated APIs can, using the `x-nullable` extension, and it is then not possible
> to distinguish a field explicitly set to `null` from an unset field
>
> An alternate design has been experimented but not released. For those interested in pushing forward this project again,
> see [this pull request][lifting-pointers]

#### Common use cases

You don't always have to resort to pointers to figure out whether a value is empty.

* The idiomatic way to check for a null/empty string is: `minLength: 1`

### Validation

All produced models implement the [Validatable] interface.

Exceptions:
- `file` types do not support validation (however generated operations may check the `maxLength` of a file)
- empty schemas (`any` type, rendered as `interface{}`) do not support validation

Therefore, type aliases constructed on either a swagger `file` or an empty schema does not implement this interface.

Validation errors:
- Returned errors are supported by the `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.

### Type aliasing

A definition may create an _aliased_ type like this:

```yaml
definitions:
  myDate:
    type: string
    format: date
```

Rendered as:
```go
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:
```yaml
definitions:
  myDate:
    type: string
    format: date
    x-nullable: true
  anArrayOfDates:
    type: array
    items:
      $ref: '#/definitions/myDate'
```

Yields:
```go
type MyDate strfmt.Date
...
type AnArrayOfDates []*MyDate
```

Realiasing

Given the above definitions, we add:

```yaml
  ...
  herDate:
    $ref: #/definitions/myDate
  hisDate:
    $ref: #/definitions/herDate
```

Rendered as (requires go1.9+):
```go
type HerDate = MyDate
```

```go
type HisDate = HerDate
```

### Extensible types

##### Objects and additional properties

Additional properties in a JSON object are represented in a go struct by `map[string]T`.

Examples:

```yaml
definitions:
  extensibleObject:
    properties:
      prop1:
        type:  integer
    additionalProperties:
      type: string
      format: date
```

Is rendered as:
```golang
type ExtensibleObject struct {
    Prop1 int64
    ExtensibleObjectProperties map[string]strfmt.Date
}
```

If there is no restriction on the additional properties:

```yaml
definitions:
  extensibleObject:
    type: object
    properties:
      prop1:
        type: integer
    additionalProperties: true
```

We get:
```golang
type ExtensibleObject struct {
    Prop1 int64
    ExtensibleObjectProperties map[string]interface{}
}
```

##### Tuples and additional items

A tuple is rendered as a structure with a property for each element of the tuple.

Example:
```yaml
definitions:
  tuple:
    type: array
    items:
    - type: integer
    - type: string
    - type: string
      format: uuid
```

Gives:
```golang
type Tuple struct {
    P0 *int64
    P1 *string
    P2 *strfmt.UUID
}
```

If we specify additional items as in:
```yaml
definitions:
  extensibleTuple:
    type: array
    items:
    - type: integer
    - type: string
    - type: string
      format: uuid
    additionalItems:
    - type: number
```
Gives:
```golang
type ExtensibleTuple struct {
    P0 *int64
    P1 *string
    P2 *strfmt.UUID
    ExtensibleTupleItems []float64
}
```

> **NOTE**: currently the P0, P1, ... names are not customizable.

### Polymorphic types

Polymorphic types are swagger's flavor for inheritance (aka _hierarchized composition_...).
The use of the `discriminator` keyword gives a special meaning to `allOf` compositions.

#### Base types
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 `required` property with `"type": "string"`.
> No validation attached to this property, save `required`, will be honored, as
> a discriminator property is implicitly an `enum` with 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:
```yaml
  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.

```go
// 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.

#### Subtypes

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:
```yaml
  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:
```go
// 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 `allOf` semantics are lost.
> Do not expand specs with polymorphic types for code generation.

You may define several such derived types.

Example:
```yaml
  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
```

```go
// 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.

#### Type composition

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:
```yaml
  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:
```go
// 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](https://github.com/go-swagger/go-swagger/issues/232).

#### Factories for base types

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:
```go
// 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]Pet` are not supported yet
> - composing tuples containing base types is not supported yet

### Serialization interfaces

<!--

JSON

XML
-->

##### Custom serializers

Tags are generally sufficient to provide proper JSON marshalling capabilities.

Models define some custom [un]marshallers in the following situations:
- tuples: array elements are dispatched in the tuple's struct
- additionalProperties: additional content is dispatched in the `map[string]...`
- subtypes of base types
- types composed of base types
- aliases on formatted types when the underlying type is not string (e.g. Date, Datetime)

<!--
##### [Un]MarshalBinary interfaces

TODO
-->

<!-- References -->

##### External types

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](../../../examples/external-types/swagger-external.yaml)
to illustrate the different capabilities to inject custom types.


Examples:

External types are typically used in top-level model definitions, like so:

```yaml
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:

```go
custom.MyExternalType
```

If no package is provided, it defaults to the models package indicated for codegen:
```yaml
definitions:
  generatedType:
    type: array
    items:
      $ref: '#/definitions/myType'

  myType:
    type: object
    x-go-type:
      type: MyExternalType
```

```sh
swagger generate models --model-package custom --target ./codegen

ls ./codegen/custom   # <- myType is NOT GENERATED
cat ./codegen/custom/generated_type.go
```

```go
package custom

type GeneratedType []MyType
```

External types may also be injected at lower schema levels:

```yaml
definitions:
  MyType:
    type: array
    items:
      type: string
      x-go-type:
        type: MyExternalString
        import:
          package: github.com/example/models/custom
```
or:
```yaml
  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:

```yaml
  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.MyType` or `map[string]external.MyType` instead of `[]*external.MyType`
> and `map[string]*external.MyType` respectively. You can use the `nullable` hint or the `x-nullable` extension
> to control this behavior.

###### Known limitations

* 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.


###### External package aliasing


The following example replaces all references to `myModel` by `github.com/example/models/MyCustomModel`.

Example:

```yaml
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:

```yaml
  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:
```go
import (
  fred "github.com/example/models/custom"
)
...
```

Some deconfliction with other known import is applied automatically. Automatic deconfliction is not perfect, though.

For example:
```yaml
  MyObject:
    type: object
    properties:
      p1:
        x-go-type:
          type: RawMessage
          import:
            package: encoding/json
          hints:
            kind: interface
```

```go
import (
  jsonext "encoding/json"
)
```


###### Embedding external types

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:
```yaml
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:

```go
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 `format` specification over the embedded type. Format will be documentary only in that case.

Other examples:
```yaml
  Raw:
    x-go-type:
      type: RawMessage
      import:
        package: encoding/json
      hints:
        kind: primitive
      embedded: true
```
```go
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:
```yaml
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
```

```go
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:
```yaml
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.


###### Validation of external types

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:
```yaml
  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.


###### External type hints

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:
```yaml
        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
```

###### Caveats with imports

At this moment, external packages and aliases are deconflicted against other known imports and variables.

Example:
```yaml
  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:
```go
import(
    ...
    jsonext "encoding/json"
    ...
    )
```

###### External package aliasing

External packages may be imported with an alias, like so:

```yaml
  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:
```go
import (
  fred "github.com/example/models/custom"
)
...
```

Some deconfliction with other known imports is applied automatically. Automatic deconfliction is not perfect, though.

For example:
```yaml
  MyObject:
    type: object
    properties:
      p1:
        x-go-type:
          type: RawMessage
          import:
            package: encoding/json
          hints:
            kind: interface
```

```go
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.

### Customizing struct tags

When a model struct is generated, tags for json are generated to keep the original name:

```go
type ObjectWithTag struct {
    StandardTag string `json:"standardTag,omitempty"`
}
```

#### Extra tags

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.

```bash
swagger generate model ... --struct-tags yaml,db
```

```go
type ObjectWithTag struct {
    StandardTag string `json:"standardTag,omitempty" yaml:"standardTag,omitempty" db:"standardTag,omitempty"`
}
```

#### Custom tags

A custom may be added to a field using the `x-go-custom-tag` extension. Like so:

#### Omit empty values

By default, a struct field is omitted when it holds the zero value (tag modifier: `omitempty`).

Required fields are never omitted.

```go
type ObjectWithTag struct {
    RequiredField *string `json:"requiredField"`
}
```

This property can be altered using the `x-omitempty` extension. Like so:
```yaml
objectWithTag:
  type: object
  properties:
    field:
      type: string
      x-omitempty: false
```

```go
type ObjectWithTag struct {
    Field string `json:"field"`
}
```

The extension does not force a required field to get the "omitempty" modifier.

#### Numerical values as string

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.

```go
type ObjectWithTag struct {
    NumericField int `json:"field,omitempty,string"`
}
```

#### XML tags

The XML name and attribute Swagger properties are used to generate extra tags.
```yaml
definitions:
 objectWithXML:
   type: object
   properties:
     field:
       type: string
       xml:
         name: xmlObject
         attribute: true
```

```go
type ObjectWithXML struct {
    Field string `json:"field,omitempty" xml:"xmlObject,attr,omitempty"`
}
```

#### The example tag

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.

```yaml
definitions:
  objectWithExample:
   properties:
     field:
       type: string
       example: "sample"
```

```go
type ObjectWithExample struct {
    Field string `json:"field,omitempty" example:"\"sample\""`
}
```

#### The description tag

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.

```yaml
definitions:
  objectWithDescription:
   properties:
     field:
       type: string
       description: "some description"
```

```go
type ObjectWithDescription struct {
    Field string `json:"field,omitempty" description:"\"some description\""`
}
```


[swagger]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schema-object
[strfmt]: https://github.com/go-openapi/strfmt
[runtime]: https://github.com/go-openapi/runtime
[File]: https://github.com/go-openapi/runtime/blob/master/file.go#L20
[Validatable]: https://github.com/go-openapi/runtime/blob/master/interfaces.go#L101
[validate]: https://github.com/go-openapi/validate
[validate-json]: https://godoc.org/github.com/go-openapi/validate#ex-AgainstSchema
[go-doc-model]: https://godoc.org/github.com/go-swagger/go-swagger/examples/generated/models
[read-only]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields-13
[all-formats]:  https://github.com/go-openapi/strfmt/blob/master/README.md
[easy-json]: https://github.com/mailru/easyjson
[json-schema]: https://tools.ietf.org/html/draft-fge-json-schema-validation-00
[lifting-pointers]: https://github.com/go-swagger/go-swagger/pull/557
