Skip to content

feat: Don't generate extra models for allOf of one model BNCH-20256 #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 6, 2021

Conversation

forest-benchling
Copy link

@forest-benchling forest-benchling commented Feb 11, 2021

Currently, we have tons of places where we do something like

	AaSequence:
      properties:
        customFields:
          allOf:
            - $ref: "#/components/schemas/CustomFields"
          description: Custom fields set on the AA sequence.

which causes an unnecessary model AaSequenceCustomFields to be generated, rather than directly referencing the existing CustomFields model.

The OpenAPI 3.1 spec is going to add support for direct sibling properties:

	AaSequence:
      properties:
        customFields:
          $ref: "#/components/schemas/CustomFields"
          description: Custom fields set on the AA sequence.

But since that may be a long ways away, we directly implement a workaround in this PR.

This workaround also applies for oneOf and anyOf.

I haven't submitted this upstream as we are using it for allOf, which has not yet been upstreamed, but we should upstream it together with the allOf work.

This PR will also be a breaking change for the benchling-api-client interface, and may require benchling-sdk to be updated accordingly.

@forest-benchling forest-benchling marked this pull request as ready for review February 11, 2021 15:02
@forest-benchling
Copy link
Author

cc @stepzhou

@forest-benchling
Copy link
Author

cc @dtkav

@dtkav
Copy link

dtkav commented Feb 11, 2021

This is great! Thank you for looking into this - one of our main outstanding spectral errors (openapi linter) is:
$ref cannot be placed next to any other properties
cc: @alexrejto

Copy link

@bowenwr bowenwr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just confirming that given something like:

allOf:
 - $ref/MyModel
 - properties:

Would still generate a new model name since it's not just the ref?

@packyg
Copy link

packyg commented Feb 12, 2021

Just confirming that given something like:

allOf:
 - $ref/MyModel
 - properties:

Would still generate a new model name since it's not just the ref?

Based on this it seems like it applies only if there is a single child that's a $ref.

Copy link

@packyg packyg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of changes in e2e tests that I'm not sure about, but looking at the spec for these I guess yeah they're a single model under an allOf


In general I agree with the idea here. I actually think it could be taken a step further, where only changes to the properties trigger a new model.

Ideally the following schema would generate a model where ParentModel.a_prop is an instance of OtherModel, not a new ParentModelAProp model, since the description and example are superfluous for code generation.

ParentModel:
  type: object
  properties:
    a_prop:
      allOf:
        - $ref: "#/components/schemas/OtherModel"
        - description: A property holding another model
          example:
            id: id_str

OtherModel:
  type: object
  properties:
    id:
      type: string

@forest-benchling
Copy link
Author

Thanks @packyg for the suggestion. In the end it looks like allOf is being implemented in triaxtec so I will probably just upstream this PR (and try to incorporate your suggestion). cc @bowenwr

@forest-benchling
Copy link
Author

A lot of changes in e2e tests that I'm not sure about, but looking at the spec for these I guess yeah they're a single model under an allOf

In general I agree with the idea here. I actually think it could be taken a step further, where only changes to the properties trigger a new model.

Ideally the following schema would generate a model where ParentModel.a_prop is an instance of OtherModel, not a new ParentModelAProp model, since the description and example are superfluous for code generation.

ParentModel:
  type: object
  properties:
    a_prop:
      allOf:
        - $ref: "#/components/schemas/OtherModel"
        - description: A property holding another model
          example:
            id: id_str

OtherModel:
  type: object
  properties:
    id:
      type: string

@packyg Sorry for the long delay, I'm finally working on upstreaming this. In your example, wouldn't we want description and example to be direct children of a_prop?

ParentModel:
  type: object
  properties:
    a_prop:
      allOf:
        - $ref: "#/components/schemas/OtherModel"
      description: A property holding another model
      example:
        id: id_str

@packyg
Copy link

packyg commented Mar 17, 2021

@packyg Sorry for the long delay, I'm finally working on upstreaming this. In your example, wouldn't we want description and example to be direct children of a_prop?

@forest-benchling That should be effectively the same, I would think

@forest-benchling
Copy link
Author

Upstream already merged

@forest-benchling
Copy link
Author

AD, going to merge this after all, so we don't have to block on upstreaming. cc @dtkav @packyg @bowenwr

@forest-benchling forest-benchling merged commit a755ed9 into main-v.0.7.3 Apr 6, 2021
@forest-benchling forest-benchling deleted the forest-one branch April 6, 2021 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants