Skip to content

[gen] support a schema for dictionary keys #3030

@hochgi

Description

@hochgi

Is your feature request related to a problem? Please describe.
Open dictionaries always have unconstrained string keys.
Typically one would define it like:

components:
  schemas:
    Order:
      
    UserOrderHistory:
      type: object
      properties:
        user_id:
          type: string
          format: uuid
        order_history:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Order'

which when used with codegen would yield code like:

case class UserOrderHistory(
  user_id: UUID,
  order_history: Map[String, Order]
)

But a common scenario is when keys are constrained.
e.g. in this case, we may want order_history to have only UUID keys instead of unconstrained strings.

Describe the solution you'd like
Anything other than unconstrained strings for dictionary keys is not supported in OpenAPI by default.
But we can consider leveraging aliasing as introduced in #2962 with a new custom extension property to enable such functionality.
e.g:

components:
  schemas:
    OrderId:
      type: string
      format: uuid
    Order:
      
    UserOrderHistory:
      type: object
      properties:
        user_id:
          type: string
          format: uuid
        order_history:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Order'
            x-string-key-ref:
              $ref: '#/components/schemas/OrderId'

codegen would then verify that the ref actually points to a string (and string only) type.
Any other type should yield a failure.

with this example we should now be able to generate code like:

case class UserOrderHistory(
  user_id: UUID,
  order_history: Map[UUID, Order]
)

or with aliased flag turned on:

case class UserOrderHistory(
  user_id: UUID,
  order_history: Map[OrderId.Type, Order]
)

Describe alternatives you've considered
There isn't really an alternative, as this is not a supported feature in OpenAPI.
Best we can do, is maybe add textual description with runtime validations in code.

Additional context
By using this mechanism, we can add any sort of format or validation supported by OpenAPI (e.g. pattern).
This would be helpful with the aliased field as Newtypes flag turned either on or off.
We could still use better types like UUID or use a validated String in generated code.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions