SoManyGoblins
SoManyGoblins

Reputation: 5917

OpenAPI Generation not respecting field name for multipart multifile upload

I have an API I'm describing with OpenAPI, it will be implemented in Java/Kotlin so I'm doing the code generation using kotlin-spring generation, using OpenAPI 3.0.2 and the plugin "org.openapi.generator" version "6.2.1"

My problem is that the field in the schema which contains the files that will be uploaded is always named file instead of respecting the name attachments i'm specifying, maybe it's a standard that I am not aware of, but this is an existing API that is already using attachments and I'd like to keep that name.

This is the schema:

  /emails/send:
post:
  responses:
    "200":
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/EmailSendResponse'
      description: Response from the send email request.
  operationId: sendEmail
  requestBody:
    required: true
    content:
      multipart/form-data:
        schema:
          $ref: '#/components/schemas/EmailSendRequest'

And the request schema:

EmailSendRequest:
  title: Email send request
  description: Contains the data required to send an email.
  required:
    - success
    - failureReason
  type: object
  properties:
    from:
      type: string
    to:
      type: string
    subject:
      type: string
    content:
      type: string
    contentType:
      type: string
      enum:
        - HTML
        - TEXT
    bcc:
      type: string
    tags:
      type: array
      items:
        type: string
    category:
      type: string
    attachments:
      type: array
      items:
        type: string
        format: binary

And this is the generated API method in Java:

@RequestMapping(
        method = [RequestMethod.POST],
        value = ["/emails/send"],
        produces = ["application/json"],
        consumes = ["multipart/form-data"]
)
fun sendEmail(@Parameter(description = "") @RequestParam(value = "from", required = false) from: kotlin.String? ,@Parameter(description = "") @RequestParam(value = "to", required = false) to: kotlin.String? ,@Parameter(description = "") @RequestParam(value = "subject", required = false) subject: kotlin.String? ,@Parameter(description = "") @RequestParam(value = "content", required = false) content: kotlin.String? ,@Parameter(description = "", schema = Schema(allowableValues = ["HTML", "TEXT"])) @RequestParam(value = "contentType", required = false) contentType: kotlin.String? ,@Parameter(description = "") @RequestParam(value = "bcc", required = false) bcc: kotlin.String? ,@Parameter(description = "") @RequestParam(value = "tags", required = false) tags: kotlin.collections.List<kotlin.String>? ,@Parameter(description = "") @RequestParam(value = "category", required = false) category: kotlin.String? ,@Parameter(description = "file detail")  @RequestPart("file") attachments: kotlin.collections.List<org.springframework.core.io.Resource>?): ResponseEntity<EmailSendResponse> {
    return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
}

As you can see, it generates with a @RequestPart("file") instead of @RequestPart("attachments")

Any clues? I've been looking at the documentation but I couldn't find anything.

Thank you!

Upvotes: 1

Views: 756

Answers (1)

tbatch
tbatch

Reputation: 1839

this appears to be an issue with the kotlin generator. I ran the generator using the schema you provided with both the kotlin-spring generated and the spring generator. The java method has the correct value for @RequestPart

default ResponseEntity<String> sendEmail(
        @Parameter(name = "from", description = "") @Valid @RequestParam(value = "from", required = false) String from,
        @Parameter(name = "to", description = "") @Valid @RequestParam(value = "to", required = false) String to,
        @Parameter(name = "subject", description = "") @Valid @RequestParam(value = "subject", required = false) String subject,
        @Parameter(name = "content", description = "") @Valid @RequestParam(value = "content", required = false) String content,
        @Parameter(name = "contentType", description = "") @Valid @RequestParam(value = "contentType", required = false) String contentType,
        @Parameter(name = "bcc", description = "") @Valid @RequestParam(value = "bcc", required = false) String bcc,
        @Parameter(name = "tags", description = "") @Valid @RequestParam(value = "tags", required = false) List<String> tags,
        @Parameter(name = "category", description = "") @Valid @RequestParam(value = "category", required = false) String category,
        @Parameter(name = "attachments", description = "") @RequestPart(value = "attachments", required = false) List<MultipartFile> attachments
    ) {
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
    }

but the generated kotlin method does not

  fun sendEmail(@Parameter(description = "") @RequestParam(value = "from", required = false) from: kotlin.String?,
                @Parameter(description = "") @RequestParam(value = "to", required = false) to: kotlin.String?,
                @Parameter(description = "") @RequestParam(value = "subject", required = false) subject: kotlin.String?,
                @Parameter(description = "") @RequestParam(value = "content", required = false) content: kotlin.String?,
                @Parameter(description = "") @RequestParam(value = "contentType", required = false)
                contentType: kotlin.String?,
                @Parameter(description = "") @RequestParam(value = "bcc", required = false) bcc: kotlin.String?,
                @Parameter(description = "") @RequestParam(value = "tags", required = false)
                tags: kotlin.collections.List<kotlin.String>?,
                @Parameter(description = "") @RequestParam(value = "category", required = false)
                category: kotlin.String?, @Parameter(description = "file detail") @Valid @RequestPart("file")
                attachments: kotlin.collections.List<org.springframework.core.io.Resource>?): ResponseEntity<kotlin.String> {
    return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
  }

If this is a deal breaker for you, then I'd recommend generating the code with the java generator. Kotlin and java are fully compatible, so you can still use the generated classes and methods in your kotlin classes.

I'd also recommend filing a bug report on the openapi generator wiki to bring attention to the issue.

Upvotes: 2

Related Questions