guardrail-dev / guardrail-dev/guardrail
Autogenerated client fails to upload a Multipart file
- Dominant language
- Scala
- Stars
- 541
- Forks
- 138
- PR merge metrics
- No merged PRs in 30d
Description
I'm writing a very simple file server. This is the endpoint to upload files:
```
/invoices:
post:
summary: Store provided PDF as an invoice
operationId: postInvoice
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
invoice:
type: string
format: binary
responses:
"200":
description: OK
```
The server is done using Akka Http and is something like:
```
pathPrefix("invoices") {
pathEnd {
post {
fileUpload("invoice") {
case (metadata, byteSource) =>
onSuccess(invoiceStorage.storeInvoice(fileName = metadata.fileName, byteSource)) { im =>
complete(StatusCodes.Created, im)
}
}
}
}
```
When I run the autogenerated code it fails with a MissingFormFieldRejection:
```
[2021-07-08 17:52:04,939] [ERROR] [akka.actor.ActorSystemImpl] [HelloAkkaHttpServer-akka.actor.default-dispatcher-6] [akka.actor.ActorSystemImpl(HelloAkkaHttpServer)] - root: Response for
Request : HttpRequest(HttpMethod(POST),http://localhost:9090/v1/invoices,List(Timeout-Access: , Host, User-Agent: akka-http/10.2.4),HttpEntity.Chunked(multipart/form-data; boundary=h4tcJ1JysgkVCWsH-YyjniaD),HttpProtocol(HTTP/1.1))
Response: Rejected(List(MissingFormFieldRejection(invoice), TransformationRejection(akka.http.scaladsl.server.directives.BasicDirectives$$Lambda$4695/0x00000008416fe040@333889d1), TransformationRejection(akka.http.scaladsl.server.directives.BasicDirectives$$Lambda$4695/0x00000008416fe040@22dde47a)))
```
but if I do that same request with the Swagger editor against that same server using the openapi.yaml used for code generation, everything goes fine:
```
[2021-07-08 17:52:44,012] [ERROR] [akka.actor.ActorSystemImpl] [HelloAkkaHttpServer-akka.actor.default-dispatcher-13] [akka.actor.ActorSystemImpl(HelloAkkaHttpServer)] - root: Response for
Request : HttpRequest(HttpMethod(POST),http://localhost:9090/v1/invoices,List(Timeout-Access: , Host, Connection: keep-alive, sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90", Accept: application/json, sec-ch-ua-mobile: ?0, User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36, Origin, Sec-Fetch-Site: cross-site, Sec-Fetch-Mode: cors, Sec-Fetch-Dest: empty, Accept-Encoding: gzip, deflate, br, Accept-Language: en-US, en;q=0.9, es-ES;q=0.8, es;q=0.7, ca;q=0.6),HttpEntity.Strict(multipart/form-data; boundary=----WebKitFormBoundaryBTY4VV6hO0kwtNxy,3378 bytes total),HttpProtocol(HTTP/1.1))
Response: Complete(HttpResponse(201 Created,List(),HttpEntity.Strict(application/json,146 bytes total),HttpProtocol(HTTP/1.1)))
```
In the logs you can see that the failing call is sending a `HttpEntity.Chunked` while the one working is sending a ` HttpEntity.Strict` although I don't know if that has something to do with the problem.
Am I doing something wrong? Is there something missing in the Swagger specification or is it a bug of guardrail?
Contributor guide
Research direction
Start by reproducing the generated client's multipart request from the provided OpenAPI schema and compare it with the successful Swagger Editor request. Inspect the generated upload call and its multipart field handling; done means the server receives the `invoice` field and the request succeeds against the Akka HTTP endpoint.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- api, backend, devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100