juhaku / utoipa

Simple, Fast, Code first and Compile time generated OpenAPI documentation for Rust
Apache License 2.0
2.48k stars 194 forks source link

Support for MultiPart Form Data Request Data for File Upload #1055

Closed kevinlutzer closed 1 month ago

kevinlutzer commented 2 months ago

Hello!

I want to be able to generate an open API json spec with an API schema containing:

requestBody:
  content:
    multipart/form-data:
      schema:
        type: object
        properties:
          # 'file' will be the field name in this multipart request
          file:
            type: string
            format: binary

Is this not currently supported by the utoipa macro?

sahithyen commented 1 month ago

I am unfamiliar with the codebase but am equally interested in a feature allowing request bodies with multipart/form-data with files.

RequestBody is holding a Map of content-type to Content which looks like this:

https://github.com/juhaku/utoipa/blob/e0c5aa749ac548cca7fd75544293865efe5d0231/utoipa/src/openapi/content.rs#L20-L44

So, the utopia structure can already hold multipart/form-data by manually defining the RequestBody.

The macro part of utoipa does not handle multipart/form-data (quick code search with no success).

I will check how to manually add such a RequestBody. After that, I would like to contribute to the macro part of creating multipart/form-data request bodies.

@juhaku Would you have time to discuss the possible API change (I hope to find a way without a breaking change)?

juhaku commented 1 month ago

In theory it should be possible. Yet it is true that the examples related to the multipart is sparse if non existing. However the macro does not support setting encoding and it need to be set manually for now.

There are ongoing changes to the macro at the moment which will change the request body definition in macro quite a bid.

#[derive(ToSchema)]
struct MyRequest {
 #[schema(format = Binary, value_type = String)] 
 imageBytes: Vec<u8>,
 // ... other fields normally
 foobar: String
}

#[utoipa::path(
  request_body(content = MyRequest, content_type = "multipart/form-data")
)]
async fn handler() {}
sahithyen commented 1 month ago

Thanks, worked out perfectly. Adding the encodings of the different fields worked out as well using the manual method.

juhaku commented 1 month ago

There is a new PR #1113 for coming utoipa 5.0.0 version with examples for file uploads in OpenAPI 3.1 specification. There are examples for multipart and as well as sending raw binary.

kevinlutzer commented 1 month ago

Awesome thanks guys!