Skip to content

Generic models do not generate OpenAPI description #5460

Open
@bitfl0wer

Description

@bitfl0wer

Consider this real-world code example:

/**
* A message batch, as received from and sent to the server in the context of re-signing messages.
* This type is generic over `T`, where `T` represents the content of the actual message. This
* means, that the specific message content depends on the concrete implementation or extension
* of the polyproto protocol.
*/
model MessageBatch<T> {
  @doc("The ID-Cert that the following messages' signatures correspond to.")    
  idCert: string,
  @doc("The actual message.")
  messages: {
      @doc("Signature of the whole message")
      signature: string,
      @doc("Arbitrary content `T`. This depends on the specific implementation or extension of the protocol.")
      content: T
  }[];
}

generates the following OpenAPI3 spec for a dummy route:

/.p2/core/v1/dummy:
    post:
      operationId: Unregistered_dummy
      parameters: []
      responses:
        '204':
          description: 'There is no content to send for this request, but the headers may be useful. '
      tags:
        - Migration - Registration not required
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - idCert
                - messages
              properties:
                idCert:
                  type: string
                  description: The ID-Cert that the following messages' signatures correspond to.
                messages:
                  type: array
                  items:
                    type: object
                    properties:
                      signature:
                        type: string
                        description: Signature of the whole message
                      content:
                        type: string
                        description: Arbitrary content `T`. This depends on the specific implementation or extension of the protocol.
                    required:
                      - signature
                      - content
                  description: The actual message.
              description: |-
                A message batch, as received from and sent to the server in the context of re-signing messages.
                This type is generic over `T`, where `T` represents the content of the actual message. This
                means, that the specific message content depends on the concrete implementation or extension
                of the polyproto protocol.
      security:
        - BearerAuth: []

The issue at hand here has to do with the fact that generic TypeSpec models do not generate OpenAPI schemas. This is somewhat understandable, as OpenAPI3 likely does not have a way to represent generic type arguments. However, all of my documentation for the TypeSpec model is lost in the compilation process, as it does not make it into the OpenAPI documentation/specification at all. Off the top of my head, I can think of two solutions for this problem:

1. Compile time monomorphization of generics

Say I have the above MessageBatch<T> model. For the sake of explanation, we assume that the T parameter is used in two different ways within my route definitions or other model definitions:

  1. T = string
  2. T = uint32

Through monomorphization, TypeSpec could generate the following OpenAPI3 schemas:

MessageBatchString and MessageBatchUint32

This way, the documentation I meticulously added to my TypeSpec model does not get lost and the model still translates to an OpenAPI3 schema in some way. In my opinion, this is better than completely "losing"/"missing out" on the entire schema.

2. Add the documentation of the generic type to every usage field in OpenAPI3 schema

This solution is perhaps simpler than the first proposal.

Assume, again, that I have the MessageBatch<T> model with two different T parameters within my project, where T = string and T = uint32.

With this proposal, the TypeSpec model would not be translated to an OpenAPI schema. Instead, the documentation of the MessageType (and, if applicable, the T generic parameter as well) would be copy-pasted into every occurrence of MessageType in the generated OpenAPI3 specification.

This way, every occurrence of MessageType in the generated OpenAPI3 schema would have documentation attached to it, making things easier for TypeSpec developers and those intending to use the OpenAPI3 schema to preview it in SwaggerUI or generate client/server code from it.

Checklist

  • Follow our Code of Conduct
  • Read the docs.
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    design:neededA design request has been raised that needs a proposalemitter:openapi3Issues for @typespec/openapi3 emittertriaged:core

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions