Description
While JSON references are useful for certain cases as described in this tutorial, they cannot "include" an entire specification and merge it into the main one. This would be helpful in organizing API specifications into modules, where each module can include a full complement of schemas, paths, etc.
An "import" feature is proposed as a pre-processor before calling the swagger parser, with a section like:
"imports": {
"collision_handling":"error|first_wins|last_wins",
"locations":[
{ "location":"URL" },
{ "location":"URL" },
...
]
}
Of course, both YAML and JSON are supported. It would be enabled by a command-line switch --enable-imports. If enabled, the pre-processor would read each of the import sources, parse it as JSON, then merge the import JSON objects with the main file. It would write the resulting JSON to a temporary file and hand that to the main engine. This raises the possibility of collisions (same keys defined in multiple sources). Collisions are resoloved using a set of rules:
- If both keys reference a map, the maps are merged
- If both keys reference an array, second array is appended to the first
- Otherwise, the
collision_handling settings controls behavior:
error is the default: an exception is thrown
first_wins means that the later definition is ignored and a warning is logged
last_wins means that the earlier definition is replaced and a warning is logged
openapi-generator version
N/A
OpenAPI declaration file content or url
common.json
{
"components": {
"schemas": {
"DateTime": {
"type":"string",
"format":"date-time"
},
"ResponseBase": {
"properties": {
"type":{
"type":"string"
}
}
},
"ErrorResponse": {
"allOf":[
{ "$ref": "#/components/schemas/ResponseBase" }
]
},
"Request": {
"properties": {
"id": {
"type": "string"
}
}
}
}
}
}
spec.json
{
"openapi": "3.0.0",
"info": {
"description": "blah",
"version": "1.0.0",
"title": "blah"
},
"imports":{
"collision_handling":"error",
"locations":[
{ "location":"common.json" }
]
},
"paths": {
"/test1": {
"post": {
"tags": [
"test"
],
"operationId": "testOp1",
"responses": {
"405": {
"description": "Invalid input",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
}
},
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Response"
}
}
}
}
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Request"
}
}
}
}
}
}
},
"components": {
"schemas": {
"ErrorResponse": {
"allOf":[
{
"type":"object",
"properties": {
"message": {
"type": "string"
}
}
}
]
},
"Request": {
"properties": {
"name": {
"type": "string"
}
}
},
"Response": {
"properties": {
"email": {
"type": "string"
}
}
}
}
}
}
When processed (there are no collisions), would produce:
{
"openapi": "3.0.0",
"info": {
"description": "blah",
"version": "1.0.0",
"title": "blah"
},
"paths": {
"/test1": {
"post": {
"tags": [
"test"
],
"operationId": "testOp1",
"responses": {
"405": {
"description": "Invalid input",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
}
},
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Response"
}
}
}
}
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Request"
}
}
}
}
}
}
},
"components": {
"schemas": {
"DateTime": {
"type":"string",
"format":"date-time"
},
"ErrorResponse": {
"allOf":[
{ "$ref": "#/components/schemas/ResponseBase" },
{
"type":"object",
"properties": {
"message": {
"type": "string"
}
}
}
]
},
"Request": {
"properties": {
"id": {
"type": "string"
},
"timestamp": {
"$ref" : "#/components/schemas/DateTime"
}
}
},
"Response": {
"properties": {
"email": {
"type": "string"
}
}
}
}
}
}
Note that ErrorResponse's allOf list has been concatenated, and Request's properties object has been merged.
Command line used for generation
New option --enable-imports would enable this feature
Steps to reproduce
Related issues/PRs
None in this repo, but in swagger-parser:
swagger-api/swagger-parser#147
Suggest a fix/enhancement
Description
While JSON references are useful for certain cases as described in this tutorial, they cannot "include" an entire specification and merge it into the main one. This would be helpful in organizing API specifications into modules, where each module can include a full complement of schemas, paths, etc.
An "import" feature is proposed as a pre-processor before calling the swagger parser, with a section like:
Of course, both YAML and JSON are supported. It would be enabled by a command-line switch
--enable-imports. If enabled, the pre-processor would read each of the import sources, parse it as JSON, then merge the import JSON objects with the main file. It would write the resulting JSON to a temporary file and hand that to the main engine. This raises the possibility of collisions (same keys defined in multiple sources). Collisions are resoloved using a set of rules:collision_handlingsettings controls behavior:erroris the default: an exception is thrownfirst_winsmeans that the later definition is ignored and a warning is loggedlast_winsmeans that the earlier definition is replaced and a warning is loggedopenapi-generator version
N/A
OpenAPI declaration file content or url
common.jsonspec.jsonWhen processed (there are no collisions), would produce:
Note that
ErrorResponse'sallOflist has been concatenated, andRequest'spropertiesobject has been merged.Command line used for generation
New option
--enable-importswould enable this featureSteps to reproduce
Related issues/PRs
None in this repo, but in swagger-parser:
swagger-api/swagger-parser#147
Suggest a fix/enhancement