SMILEY4 / ktor-swagger-ui

Kotlin Ktor plugin to generate OpenAPI and provide Swagger UI
Apache License 2.0
178 stars 33 forks source link

Unable to use multiple files with multipartBody #127

Closed Shreemanarjun closed 1 month ago

Shreemanarjun commented 2 months ago

Issue

I want to accept multiple files with given doc name in swagger ui. the docName part is rendering correctly as it Array but when i define it show somehow different. i think somehow the plugin unable to overwrite the file class which causes the given problem.

Screenshot

Screenshot 2024-09-04 at 3 08 47 PM

Swagger Config


schemas {
            overwrite<File>(
                Schema<Any>().also {
                    it.type = "string"
                    it.format = "binary"
                }
            )
        }

api.json


["java.io.File"](http://localhost:8181/api.json): {
"title": "File",
"type": "object",
"properties": {}
}

Solution needed: if the file format is binary and type somehow will be string then it will render as usual.

  java.io.File:
      title: File
      type: string
      format: binary
      properties: {}

Route


     post("/verify", {
            tags = listOf("Doctor")
            request {
                multipartBody {
                    part<Array<String>>(
                        name = "docName"
                    )
                    part<Array<File>>(
                        name = "docs",

                        )
                }

            }

        }) {
            val multipartData = call.receiveMultipart()
            var fileDescription = ""
            var fileName = ""
            multipartData.forEachPart { part ->
                when (part) {
                    is PartData.FormItem -> {
                        fileDescription = part.value
                    }

                    is PartData.FileItem -> {
                        fileName = part.originalFileName as String
                        val fileBytes = part.streamProvider().readBytes()
                        val savedfile = File("/uploads/$fileName")
                        savedfile.writeBytes(fileBytes)
                        println("file uploaded: $fileName into ${savedfile.absolutePath}")
                    }

                    else -> {}
                }
                part.dispose()
            }

            call.respondText("$fileDescription is uploaded to 'uploads/$fileName'")

        }
SMILEY4 commented 1 month ago

Hi,

overwrite can only overwrite "top level" types, i.e. you are overwriting "File" but the type in the body is "Array".

You can solve this by defining the type of the body as:

multipartBody {
    //...
    part(
        name = "docs",
        type = array<File>() // manually define the type as an array of "File"
    )
}