Repository navigation
fix(kotlin-client): actually send the jvm-vertx form body - #25623
Open
khayashi4337 wants to merge 6 commits into
Open
khayashi4337 wants to merge 6 commits into
khayashi4337 wants to merge 6 commits into
Conversation
jvm-vertx populated a `form` MultiMap for form params but dispatched the
request via `.send()` only -- the form body was silently dropped, so every
urlencoded/multipart operation reached the wire with an empty body.
Send it: `.sendForm(form)` for urlencoded forms and
`.sendMultipartForm(form)` with a `MultipartForm` for multipart.
While here, encode multipart correctly: file params went through
`form.add("name", file.toString())` which sends the file's path string,
not its content -- they now use `binaryFileUpload(name, it.name,
it.absolutePath, contentType)`. Array form params used a single
toString() blob -- they now expand via `toMultiValue(...)` (attribute
entries for multipart, a MultiMap add for urlencoded).
Fixture kotlin-vertx-form-send.yaml + a test asserting the form reaches
the send call for both content types.
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The vertx form body is now actually sent: sendForm for urlencoded and sendMultipartForm + binaryFileUpload for multipart (file content instead of its path string). Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… jvm-vertx
sendForm()/sendMultipartForm() set Content-Type themselves; emitting
putHeader("Content-Type", ...) on a form operation makes Vert.x 5.1.5
throw IllegalStateException for media types with parameters such as
"application/x-www-form-urlencoded; charset=UTF-8".
- remove the manual Content-Type putHeader for form operations
- drop the invalid OAS2 "consumes:" key from the OAS3 fixture
- add a charset-parametrized urlencoded operation to the fixture
- assert array serialization in both form flavors
(toMultiValue/collectionFormat entries for urlencoded,
form.attribute for multipart)
- regenerate kotlin-jvm-vertx-* samples (12 files, all deletions)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 11, 2026
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 15 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
3 tasks done
…send-form-body Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…alues in jvm-vertx - with mapFileBinaryToByteArray the file parameter arrives as a ByteArray, which has no `name`/`absolutePath`; send the bytes through the Buffer-based binaryFileUpload overload so the generated code compiles in that configuration - form arrays of enums now put each item's wire `value` into toMultiValue, matching the single-enum handling (previously the enum constant's toString went on the wire) - tighten the form tests: sendForm/sendMultipartForm are asserted inside each generated operation, the encoding-declared contentType must reach binaryFileUpload, and a ByteArray upload variant is covered Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…send-form-body Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
kotlinclient withlibrary=jvm-vertxbuilds a form for operations with form parameters but never sends it, so everyapplication/x-www-form-urlencodedandmultipart/form-datarequest goes out with an empty body.Reproducer
Any operation with form parameters, e.g.
updatePetWithFormanduploadFilein the petstore samples. On master,samples/client/petstore/kotlin-jvm-vertx-jackson/.../PetApi.kt:The
formis populated and then dropped:.send()sends no body. In the multipart case the file part would also be wrong even if it were sent, becausefile.toString()is the file's path, not its content. Array form parameters are added as a singletoString()of the whole list.Fix
In
kotlin-client/libraries/jvm-vertx/api.mustache:MultiMapand send it with.sendForm(form).io.vertx.ext.web.multipart.MultipartFormand send it with.sendMultipartForm(form).form.binaryFileUpload(baseName, it.name, it.absolutePath, contentType). WithmapFileBinaryToByteArray=truethe parameter is aByteArray, so the bytes are sent through theBufferoverload instead:form.binaryFileUpload(baseName, baseName, Buffer.buffer(it), contentType).contentTypeis the part's encodingcontentTypewhen the spec sets one, otherwiseapplication/octet-stream.form.attribute(baseName, value).toMultiValue(list, collectionFormat)helper:form.add(name, values)for urlencoded and oneform.attribute(name, value)per returned value for multipart.toMultiValuereturns one value per item only forcollectionFormatmulti. For other formats, including thecsvthat the generator assigns to OAS 3 form arrays without anencodingentry, it returns one joined value (tags=a,b). That default is existing generator behavior and is unchanged here. For arrays of enums, each item's wirevalueis passed totoMultiValue, as the single-enum case already does.request.putHeader("Content-Type", …).sendFormandsendMultipartFormset the header themselves. With a preset header, Vert.x 5.1.5 (the version in the samples'build.gradle) throwsIllegalStateExceptionwhen the media type is anything other than exactlyapplication/x-www-form-urlencodedormultipart/form-data, e.g.application/x-www-form-urlencoded; charset=UTF-8. A multipart operation is therefore always sent asmultipart/form-data..send(), and operations with a body parameter still use.sendBuffer(...). Neither path changes.After regeneration, the multipart operation in the sample reads:
Tests
modules/openapi-generator/src/test/resources/3_0/kotlin/kotlin-vertx-form-send.yaml(added by this PR) has a urlencoded operation with an array fieldtagsand an enum array field, a second urlencoded operation declared asapplication/x-www-form-urlencoded; charset=UTF-8, and a multipart operation with a filemyFile(whoseencodingdeclarescontentType: image/jpeg) and an array fieldlabels.testJvmVertxFormBodyIsSent(new).sendForm(form)and the multipart one with.sendMultipartForm(form);form.binaryFileUpload("myFile"with"image/jpeg"and noform.add("myFile"; noputHeader("Content-Type"anywhere in the file;form.add("tags", toMultiValue(it.toList(), "csv")); the completetoMultiValue(…).forEach { form.attribute("labels", it) }expression; enum array items sent as.valuetestJvmVertxFormFileByteArray(new)mapFileBinaryToByteArray=true, the file part is sent withBuffer.buffer(it)./mvnw -nsu -Denforcer.skip=true -pl modules/openapi-generator -am -Dtest=KotlinClientCodegenApiTest -Dsurefire.failIfNoSpecifiedTests=false testapi.mustachechange reverted (tests kept; each new test run on its own)testJvmVertxFormBodyIsSentandtestJvmVertxFormFileByteArrayfailSamples
12 files changed in
kotlin-jvm-vertx-gson,kotlin-jvm-vertx-jackson,kotlin-jvm-vertx-jackson-coroutinesandkotlin-jvm-vertx-moshi:PetApi.kt: the two form operations now send their form, and theirputHeader("Content-Type", …)lines are gone.PetApi.kt,StoreApi.kt,UserApi.kt: operations without form parameters lose an empty line that the removed template line used to leave. This is whitespace only.All four directories are compiled by
samples-kotlin-client.yaml. The petstore samples have no array form parameter, so the array branches are covered by the generator test above.This PR and its sibling PRs #25622, #25624 and #25625 (
$escaping in wire names) all touchKotlinClientCodegenApiTestand neighboring kotlin-client templates; whichever merges first, I will rebase the others.cc @wing328 @karismann @Zomzog @andrewemery @4brunu @yutaka0m @stefankoppier @e5l (Kotlin technical committee)
PR checklist
./mvnw -pl modules/openapi-generator-cli -am package -DskipTests) and regenerated the jvm-vertx configs with./bin/generate-samples.sh; the resulting diff is committed.export_docs_generators.shnot run: no generator option or metadata changes.Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
🤖 Generated with Claude Code