guardrail-dev / guardrail-dev/guardrail

Autogenerated client fails to upload a Multipart file

Open
#1,158 1 comment 0 reactions 0 assignees View on GitHub
bug good first issue help wanted scala-akka-http
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.