microsoft / typespec

https://typespec.io/
MIT License
4.43k stars 207 forks source link

[Bug]: @doc on bytes doesn't output OpenAPI description #3457

Open maxbeatty opened 4 months ago

maxbeatty commented 4 months ago

Describe the bug

If a @doc decorator is used on a bytes field, the resulting OpenAPI spec does not include a description for that field.

model UploadParameters {
  @doc("A `.zip` archive file.") 
  file: bytes,
}
components:
  schemas:
    UploadParametersMultiPart:
      type: object
      required:
        - file
      properties:
        file:
          type: string
          format: binary

If file is changed to string, then a description appears as expected:

model UploadParameters {
  @doc("A `.zip` archive file.") 
  file: string,
}
components:
  schemas:
    UploadParametersMultiPart:
      type: object
      required:
        - file
      properties:
        file:
          type: string
          description: A `.zip` archive file.

Other types like int16, duration, and unknown also work as expected.

Reproduction

Playground

Checklist

Jameschen594 commented 1 month ago

Hey, TypeSpec Team. Great work on building such a powerful tool for defining and modeling APIs. This is my first time contributing to an open-source project, and I am interested in helping with an issue I encountered in this repository. I want to work on the ticket, although I am still determining if I will be able to resolve it. I have set up my environment and have been reviewing the codebase to understand the scope of the problem. Upon initial investigation, I noticed a test in decorators.test.ts that describes the @ doc decorator. While I don't want to make assumptions prematurely, it seems that the getDoc function might not retrieve the description from the bytes type when dealing with multipart/form-data and HTTP body, which could lead to a lack of output in the OpenAPI description. I am continuing to explore the codebase to gain a deeper understanding. However, I am reaching out to seek any advice you may have or to inquire if this issue is appropriate for a first-time contributor to work on.

Jameschen594 commented 3 weeks ago

The documentation indicates that this behavior is intentional: Bytes does not support multipart/form-data. You can find more details here: OpenAPI Documentation. Should we modify the implementation?

maxbeatty commented 3 weeks ago

This may not be the right source of truth, but Swagger states:

In OpenAPI 3.0, you can describe files uploaded directly with the request content and files uploaded with multipart requests. Use the requestBody keyword to describe the request payload containing a file. Under content, specify the request media type (such as image/png or application/octet-stream). Files use a type: string schema with format: binary or format: base64, depending on how the file contents will be encoded.

This is consistent with the current TypeSpec implementation in that bytes gets translated to type: string, format: binary. It is also outputting the correct content type

@post
upload(
    @header contentType: "multipart/form-data",
    @doc("A `.zip` archive file") file: bytes,
  )
requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
              required:
                - file

Multipart requests appear to be supported and encouraged https://swagger.io/docs/specification/v3_0/describing-request-body/file-upload/#:~:text=goes%20there%5D-,Upload%20via%20Multipart%20Requests,-To%20describe%20a

But this is getting a little off topic of the original issue of the docs not working.