oasdiff: Need an option to expand "allOf" blocks for proper semantical difference

Describe the bug “allOf” construct from JSON-schema is a recommended and widely used approach to combine schemas in OpenAPI specs and avoid copy-pasting. Sometimes we refactor specs and replace plain schemas with full equivalents using “allOf”. As far as I can see OASDIFF always detects it as a breaking change, even if underlying schemas are fully equivalent.

To Reproduce Steps to reproduce the behavior:

  1. Run `oasdiff -format text -base oasdiff-test1.yml -revision oasdiff-test12.yml
  2. With oasdiff-allof-test.zip
  3. Receive the following result:
### Modified Endpoints: 1
-------------------------
GET /test
- Responses changed
  - Modified response: 200
    - Content changed
      - Modified media type: application/json
        - Schema changed
          - Property 'AllOf' changed
            - 2 schemas added
          - Type changed from 'object' to ''
          - Properties changed
            - Deleted property: description
            - Deleted property: name         
 

Expected behavior I expect to have a command line option to get rid of “allOf” and convert them to equivalent inline schemas. So that two semantically equivalent specs (like in my example) will not be considered as different:

### Modified Endpoints: 0

#154 could be about the same thing

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 33 (4 by maintainers)

Most upvoted comments

@wtrocki , how do you plan to flatten oneOf/anyOf? Is it really possible?

allOf can be flattened to get fully equivalent schema, but oneOf/anyOf cannot…

@reuvenharrison I have investigated the issue and there are a couple of ways to do it:

  1. Preprocessing step that does flattening as mentioned by @anikitin
  2. Write dedicated optional flattening for oneOf and allOf in oasDiff controlled by cli flags

IMHO option nr2 is superior as it would enable oasdiff to test the whole experience end to end and minimize issues like duplicate reports when schema.component is reused across different apis. Transformation logic should cater to 3 different constructs:

Approach for flattening/normalization/transformation

When performing flattering 2 different strategies can be taken:

  1. Whole schema flattening involving resolving every dependency
  2. Targetted flattening like mentioned in this jira

Full Schema Flatten

. This approach will fix some of the confusion with Cardiff reporting multiple breaking changes for a single model change. It will focus on the final API. There are some existing examples of golang libraries that perform such mechanisms:

Flattenining strategies

Involves triggering dedicated transformations:

We’re making progress on this issue and want to test our code with real use cases. Could any of you provide a spec that uses allOf and specify the library used for flattening? Your input would be really helpful. Thanks.

As I posted earlier in this chat I used a combination of https://github.com/mokkabonna/json-schema-merge-allof and https://github.com/equinor/openapi-flattener. First - as is, second needed to change to support ‘allOf’ constructs in different parts of OpenAPI spec (e.g. callbacks, parameters) which was not supported originally.

@reuvenharrison , understood. Unfortunately I have almost zero experience with Golang and NodeJS. I use my own fork of https://github.com/equinor/openapi-flattener to dereference original OpenAPI and remove “allOf” before feeding it to oasdiff. I will need some time to polish my forked version (significantly improved original one), then I will publish the link here.

This project can potentially be used to implement this feature: https://github.com/mokkabonna/json-schema-merge-allof