Transforming specifications
The swagger toolkit allows some transformation to be carried out with a specification.
Currently it is possible to apply the following transforms:
- expansion: this expands all
$ref's in a spec - minimal flattening: carries on minimal transformation to a spec to be workable for the swagger codegen
- full flattening: performs minimal flattening and in addition, replaces all complex constructs in schemas by named definitions
- mixin: merges one or more specifications into a primary spec
In addition, it is possible to compare specs (diff) to inspect breaking changes in the API.
Expansion
Expanding a spec may prove useful to validate a schema, produce documentation or test cases. The primary intent is not code generation.
NOTE: Circular
$refare detected and remain as local$ref. Remote circular$refremain remote (favorflattento regroup all remote$refunder one single root document).
Usage:
swagger expand {spec}
or
swagger flatten --with-expand {spec}`
Full list of available options for expand and for flatten.
or with codegen commands:
swagger generate [model|server|client|operation|...] --spec={spec} --with-expand
NOTE: codegen may fail in some situations with spec expansion:
- polymorphism: the original intent of the
$refpointing to a discriminated type (i.e. extends type...) is lost with expansion- duplicate names: expansion of
$refintended for type reuse may produce duplicate type identifiers- too many generated files: expansion of large specs may lead to many independent anonymous structures
Minimal flattening
This transform makes complex JSON $ref amenable to analysis and code generation.
Minimal flattening attempts to minimally distort the original specification intent, while ensuring workable codegen.
Minimal flattening does:
- bundle all external
$refs into the local document - resolve JSON pointers to anonymous places in the document (e.g.
"$ref": "#/definitions/thisModel/properties/codeName") - resolve
$refs in swagger-specific sections:parametersandresponses, so the only remaining$refs are located in schemas
All $refs in the resulting spec are thus only found in schema, with the canonical form: "$ref": "#/definitions/modelName".
Usage:
swagger flatten {spec}
or more explicitly:
swagger flatten --with-flatten=minimal {spec}
This is the default option for codegen commands:
swagger generate [model|server|client|operation|...] --spec={spec}
NOTE:
$refbundling / pointer resolving may in some cases produce duplicate names. The flattener tries to resolve duplicates whenever possible (such as when a child identifier duplicates its parent). When such resolution is not possible, an "OAIGen" suffix is added to the definition name (a warning is issued). You may use thex-go-nameextension here to set a more suitable name for the generated type.
Full flattening
Full flattening is useful to factorize data model objects into simpler structures.
Complex structures (i.e. objects with properties or schemas with an
allOfcomposition) are moved to standalone definitions. Arrays and map constructs (e.g. AdditionalProperties) are not considered complex.
Usage:
swagger flatten --with-flatten=full {spec}
Or with codegen commands:
swagger generate [model|server|client|operation|...] --spec={spec} --with-flatten=full
NOTE: this used to be the default for codegen commands with releases 0.13 and 0.14. This behavior has been reverted with release 0.15.
You may not like the automatic names chosen for the new structures (e.g. myModelAllOf3, myModelAdditionalPropertiesAdditionalProperties ...).
Again, the x-go-name extension is the way to generate custom names that are easier to use in your API code.
Ex:
definitions:
complexArray:
schema:
type: array
items:
type: object # <- inline schema for items
properties:
prop1:
type: integer
Is factorized as:
definitions:
complexArray:
schema:
type: array
items:
$ref: '#/definitions/complexArrayItems'
complexArrayItems:
type: object
properties:
prop1:
type: integer
Other flattening options
The --with-flatten option supports the following additional arguments:
verbose,noverbose: allows/mute warnings about the transformationremove-unused: removes unused definitions after expansion or flattening
NOTE: you may specify multiple options like this:
swagger flatten {spec} --with-flatten=remove-unused --with-flatten=full
Mixin
Usage:
swagger mixin {primary spec} [{spec to merge}...]
Full list of available options here.
Roadmap
This set of features is essentially provided by the github.com/go-openapi/analysis package.
Feel free to contribute new features to this repo.
Currently, here is a todo list of improvements planned to the spec preprocessing feature:
- in full flatten mode, more options to control how allOf are handled
- in full flatten mode propagating
x-go-name(as prefix) to newly created definitions. As creating new definitions introduces some naming conventions. If a x-go-name has been set in the original structure, new names should remain consistent with their container... - struct name analysis and better prediction/resolution of duplicate identifiers