openapi-format icon indicating copy to clipboard operation
openapi-format copied to clipboard

sort - order not always preserved on certain sub-objects

Open ed-randall-blk opened this issue 1 year ago • 2 comments

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"
              }
            }
          },

ed-randall-blk avatar Jul 07 '23 10:07 ed-randall-blk

hi @ed-randall-blk

I'll need to investigate this further, on why this sorting is happening.

thim81 avatar Jul 09 '23 18:07 thim81

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.

2023-09-17 at 16 23 53@2x

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.

thim81 avatar Sep 17 '23 14:09 thim81