hashicorp / terraform-plugin-codegen-openapi

OpenAPI to Terraform Provider Code Generation Specification
Mozilla Public License 2.0
49 stars 9 forks source link

Consider how to handle valid `allOf` constraints - schema composition #56

Open austinvalle opened 11 months ago

austinvalle commented 11 months ago

References:

Background

Usage of the allOf constraint describes a JSON schema that must match all subschemas defined, which I've seen used as a way to compose multiple schemas or share a common base model.

Note from JSON schema docs:

Instances must independently be valid against “all of” the schemas in the allOf.

The PetStore Expanded 3.0 spec has an example of this:

# .. rest of OAS
components:
  schemas:
    Pet:
      allOf:
        - $ref: '#/components/schemas/NewPet'
        - type: object
          required:
          - id
          properties:
            id:
              type: integer
              format: int64

    NewPet:
      type: object
      required:
        - name  
      properties:
        name:
          type: string
        tag:
          type: string 

Proposal

I'm wondering for something like above if we can consider the schema as both of them combined, for the example above:

Original

Pet:
  allOf:
    - $ref: "#/components/schemas/NewPet"
    - type: object
      required:
        - id
      properties:
        id:
          type: integer
          format: int64

NewPet:
  type: object
  required:
    - name
  properties:
    name:
      type: string
    tag:
      type: string

Combined

Pet:
  type: object
  required:
    - id
    - name
  properties:
    id:
      type: integer
      format: int64
    name:
      type: string
    tag:
      type: string

Possible IR output

{
    "name": "pet",
    "schema": {
        "attributes": [
            {
                "name": "id",
                "int64": {
                    "computed_optional_required": "required"
                }
            },
            {
                "name": "name",
                "string": {
                    "computed_optional_required": "required"
                }
            },
            {
                "name": "tag",
                "string": {
                    "computed_optional_required": "computed_optional"
                }
            }
        ]
    }
}

Notes

austinvalle commented 11 months ago

Other use-cases of allOf from the kubernetes API where there is only one entry (possibly for overriding description?):

https://github.com/kubernetes/kubernetes/blob/3ac83f528dde9d6f37f0ca164d5642226f2380a7/api/openapi-spec/v3/apis__apps__v1_openapi.json#L5637-L5644

"fieldsV1": {
  "allOf": [
    {
      "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1"
    }
  ],
  "description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type."
},
raphaelfff commented 2 weeks ago

I started some work here: https://github.com/raphaelfff/terraform-plugin-codegen-openapi/pull/1