openapi-format
openapi-format copied to clipboard
sort - order not always preserved on certain sub-objects
My goal is to create normalised openapi.json files which developers can confidently review in a PR before deploying to apigee. This tool seems promising in helping us achieve that.
Unfortunately I'm experiencing unexpected sort side-effects which run contrary to the described behaviour:
The fields that are not specified will keep their order like it is in the original OpenAPI document, so only defined fields will be re-ordered.
Just using the default sorting, sub-properties eg auditStatus
seem to have a reverse-alpha sort applied. Is there a way to configure that (other than essentially declaring the entire schema ordering in the config file, right down to the leaf level)?
Input:
"schema": {
"items": {
"properties": {
"auditStatus": {
"readOnly": true,
"type": "string"
},
"columnType": {
"type": "string"
},
"createdBy": {
"readOnly": true,
"type": "string"
},
"createdDate": {
"format": "date-time",
"readOnly": true,
"type": "string"
},
"customValidationType": {
"type": "string"
},
"dataContractColumnValidations": {
"items": {
"properties": {
"auditStatus": {
"readOnly": true,
"type": "string"
},
"createdBy": {
"readOnly": true,
"type": "string"
},
"createdDate": {
"format": "date-time",
"readOnly": true,
"type": "string"
},
"customValidationId": {
"format": "int32",
"type": "integer"
},
"dataContractColumnId": {
"format": "int32",
"type": "integer"
},
"id": {
"format": "int32",
"type": "integer"
},
"lastModifiedBy": {
"readOnly": true,
"type": "string"
},
"lastModifiedDate": {
"format": "date-time",
"readOnly": true,
"type": "string"
}
},
"type": "object"
},
"type": "array"
},
"description": {
"type": "string"
},
"id": {
"format": "int32",
"readOnly": true,
"type": "integer"
},
"isActive": {
"type": "boolean"
},
"lastModifiedBy": {
"readOnly": true,
"type": "string"
},
"lastModifiedDate": {
"format": "date-time",
"readOnly": true,
"type": "string"
},
"name": {
"type": "string"
},
"parameterType": {
"type": "string"
},
"rule": {
"type": "string"
},
"scalarModelContractValidations": {
"items": {
"properties": {
"auditStatus": {
"readOnly": true,
"type": "string"
},
"createdBy": {
"readOnly": true,
"type": "string"
},
"createdDate": {
"format": "date-time",
"readOnly": true,
"type": "string"
},
"customValidationId": {
"format": "int32",
"type": "integer"
},
"id": {
"format": "int32",
"type": "integer"
},
"lastModifiedBy": {
"readOnly": true,
"type": "string"
},
"lastModifiedDate": {
"format": "date-time",
"readOnly": true,
"type": "string"
},
"scalarModelContractId": {
"format": "int32",
"type": "integer"
}
},
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"type": "array"
}
},
Output:
"schema": {
"type": "array",
"items": {
"properties": {
"auditStatus": {
"type": "string",
"readOnly": true
},
"columnType": {
"type": "string"
},
"createdBy": {
"type": "string",
"readOnly": true
},
"createdDate": {
"type": "string",
"format": "date-time",
"readOnly": true
},
"customValidationType": {
"type": "string"
},
"dataContractColumnValidations": {
"type": "array",
"items": {
"properties": {
"auditStatus": {
"type": "string",
"readOnly": true
},
"createdBy": {
"type": "string",
"readOnly": true
},
"createdDate": {
"type": "string",
"format": "date-time",
"readOnly": true
},
"customValidationId": {
"type": "integer",
"format": "int32"
},
"dataContractColumnId": {
"type": "integer",
"format": "int32"
},
"id": {
"type": "integer",
"format": "int32"
},
"lastModifiedBy": {
"type": "string",
"readOnly": true
},
"lastModifiedDate": {
"type": "string",
"format": "date-time",
"readOnly": true
}
},
"type": "object"
}
},
"description": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int32",
"readOnly": true
},
"isActive": {
"type": "boolean"
},
"lastModifiedBy": {
"type": "string",
"readOnly": true
},
"lastModifiedDate": {
"type": "string",
"format": "date-time",
"readOnly": true
},
"name": {
"type": "string"
},
"parameterType": {
"type": "string"
},
"rule": {
"type": "string"
},
"scalarModelContractValidations": {
"type": "array",
"items": {
"properties": {
"auditStatus": {
"type": "string",
"readOnly": true
},
"createdBy": {
"type": "string",
"readOnly": true
},
"createdDate": {
"type": "string",
"format": "date-time",
"readOnly": true
},
"customValidationId": {
"type": "integer",
"format": "int32"
},
"id": {
"type": "integer",
"format": "int32"
},
"lastModifiedBy": {
"type": "string",
"readOnly": true
},
"lastModifiedDate": {
"type": "string",
"format": "date-time",
"readOnly": true
},
"scalarModelContractId": {
"type": "integer",
"format": "int32"
}
},
"type": "object"
}
}
},
"type": "object"
}
}
},
hi @ed-randall-blk
I'll need to investigate this further, on why this sorting is happening.
hi @ed-randall-blk
The sorting is applied based on the default: "schema": ["description", "**type**", "**items**", "properties", "**format**", "example", "default"]
since the properties are part of the "schema" elements in your OpenApi spec.
This is the expected behavior and would help you spot differences more easily since all the "schema" properties are always sorted in the same order.
The property "read-only" is not part of the defined "schema" field order, so it is put at the end. If there were more "undefined" properties, they all would be put at the end but respecting their original order.