apple / apple/swift-openapi-generator
Multipart form properties codegen is not typesafe
- Dominant language
- Swift
- Stars
- 2k
- Forks
- 182
- Avg merge
- 13h 28m
- Merged PRs (30d)
- 5
Description
### Motivation
One of the main benefits I get from using swift-openapi-generator is type safety for client code.
However, for multipart form upload requests, it seems like the property codegen is not typesafe, where all properties just get a generic `HTTPBody` payload.
For example, given this OpenAPI document:
```yaml
/uploadFile:
post:
operationId: uploadFile
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
description:
type: string
description: A text description of the uploaded file
count:
type: integer
description: An integer value associated with the upload
imageFile:
type: string
format: binary
description: The image file to upload
required:
- description
- count
- imageFile
```
This code is generated for the request body type:
```swift
enum Body: Sendable, Hashable {
enum MultipartFormPayload: Sendable, Hashable {
struct DescriptionPayload: Sendable, Hashable {
var body: OpenAPIRuntime.HTTPBody
init(body: OpenAPIRuntime.HTTPBody) {
self.body = body
}
}
case description(OpenAPIRuntime.MultipartPart)
struct CountPayload: Sendable, Hashable {
var body: OpenAPIRuntime.HTTPBody
init(body: OpenAPIRuntime.HTTPBody) {
self.body = body
}
}
case count(OpenAPIRuntime.MultipartPart)
struct ImageFilePayload: Sendable, Hashable {
var body: OpenAPIRuntime.HTTPBody
init(body: OpenAPIRuntime.HTTPBody) {
self.body = body
}
}
case imageFile(OpenAPIRuntime.MultipartPart)
case undocumented(OpenAPIRuntime.MultipartRawPart)
}
case multipartForm(OpenAPIRuntime.MultipartBody)
}
```
So at the call site, you're responsible for producing `HTTPBody` values that respect the schema, but you get no compile-type safety if you make a mistake:
```swift
let multipartBody: MultipartBody = [
.description(.init(payload: .init(body: "This is a test image upload"))),
.count(.init(payload: .init(body: "42"))),
.imageFile(.init(payload: .init(body: .init(fileData)))),
]
```
Ideally, the codegen would produce type safe property payload initializers:
```swift
let multipartBody: MultipartBody = [
.description(.init(payload: .init(value: "This is a test image upload"))),
.count(.init(payload: .init(value: 42))),
.imageFile(.init(payload: .init(value: fileData))),
]
```
and you'd get a compiler failure if you passed say a `Swift.String` as the count value.
### Proposed solution
Ideally, the codegen would produce type safe property payload initializers:
```swift
let multipartBody: MultipartBody = [
.description(.init(payload: .init(value: "This is a test image upload"))),
.count(.init(payload: .init(value: 42))),
.imageFile(.init(payload: .init(value: fileData))),
]
```
and you'd get a compiler failure if you passed say a `Swift.String` as the count value.
### Alternatives considered
_No response_
### Additional information
_No response_
Contributor guide
Research direction
Start by generating the multipart request body from the OpenAPI document in the issue and inspect the generated Body.MultipartFormPayload types. Trace the multipart form property code generation, then verify that string, integer, and binary properties expose schema-appropriate initializers and reject mismatched values at compile time.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- openapi, swift
- Domain
- api, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100