[scala-sttp4-jsoniter] support set parameters (uniqueItems arrays) in query, header, path and cookie parameters - #24301
Conversation
… query, header, path and cookie parameters Parameters whose schema has `uniqueItems: true` are generated as Scala `Set`, but the serializers only matched `Seq`, so any `Set` parameter — including `Set[String]` — failed to compile with a `Mirror.Of[Set[...]]` error. This predates the enum-array work; `Set` was never handled. Add `Set[p]` / `Option[Set[p]]` cases to FormSerializable, HeaderSerializable, PathSerializable and CookieSerializable. Because `Set` is invariant (unlike the covariant `Seq`), the element type is bound and dispatched on via `erasedValue`: primitives and enums both convert to `Seq` and reuse the existing array serialization, so all style/explode combinations keep working. Non-enum, non-primitive element types fail with a clear compile-time error. Extend the sample spec with a `Set` of referenced enums (colors/PetColor) and a `Set` of primitives (uniqueTags) so the samples build exercises both paths.
There was a problem hiding this comment.
2 issues found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/scala-sttp4-jsoniter/README.md">
<violation number="1" location="samples/client/petstore/scala-sttp4-jsoniter/README.md:98">
P2: The new Models entry points to `PetColor.md`, but this generated sample does not contain that file, so the README link returns a missing page. Adding the generated model documentation (or removing this entry until it is generated) keeps the model index navigable.</violation>
</file>
<file name="samples/client/petstore/scala-sttp4-jsoniter/src/main/scala/org/openapitools/client/api/PetApi.scala">
<violation number="1" location="samples/client/petstore/scala-sttp4-jsoniter/src/main/scala/org/openapitools/client/api/PetApi.scala:134">
P2: An empty optional `colors` set is serialized as `colors=` rather than omitted. This can make a request behave differently from the OpenAPI contract (and may be rejected as an invalid empty color); guarding serialization on `colors.nonEmpty` would preserve omission semantics.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| - [Category](Category.md) | ||
| - [Order](Order.md) | ||
| - [Pet](Pet.md) | ||
| - [PetColor](PetColor.md) |
There was a problem hiding this comment.
P2: The new Models entry points to PetColor.md, but this generated sample does not contain that file, so the README link returns a missing page. Adding the generated model documentation (or removing this entry until it is generated) keeps the model index navigable.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/scala-sttp4-jsoniter/README.md, line 98:
<comment>The new Models entry points to `PetColor.md`, but this generated sample does not contain that file, so the README link returns a missing page. Adding the generated model documentation (or removing this entry until it is generated) keeps the model index navigable.</comment>
<file context>
@@ -95,6 +95,7 @@ Class | Method | HTTP request | Description
- [Category](Category.md)
- [Order](Order.md)
- [Pet](Pet.md)
+ - [PetColor](PetColor.md)
- [PetStatus](PetStatus.md)
- [Tag](Tag.md)
</file context>
There was a problem hiding this comment.
this generator doesn't come with auto-generated docs for APIs and models at the moment. would be nice to have but definitely not within the scope of this change.
There was a problem hiding this comment.
You're right that the generator doesn't produce those API/model docs yet, so that part is out of scope for this change. The parent comment was too broad for this PR.
| val requestURL = | ||
| uri"$baseUrl/pet/findByTags" | ||
| .addParams(FormSerializable.serialize("tags", tags, FormStyleFormat.FORM, false): _*) | ||
| .addParams(FormSerializable.serialize("colors", colors, FormStyleFormat.FORM, false): _*) |
There was a problem hiding this comment.
P2: An empty optional colors set is serialized as colors= rather than omitted. This can make a request behave differently from the OpenAPI contract (and may be rejected as an invalid empty color); guarding serialization on colors.nonEmpty would preserve omission semantics.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/scala-sttp4-jsoniter/src/main/scala/org/openapitools/client/api/PetApi.scala, line 134:
<comment>An empty optional `colors` set is serialized as `colors=` rather than omitted. This can make a request behave differently from the OpenAPI contract (and may be rejected as an invalid empty color); guarding serialization on `colors.nonEmpty` would preserve omission semantics.</comment>
<file context>
@@ -121,11 +124,15 @@ case class PetApi[Auth <: org.openapitools.client.core.Authorization] private (b
val requestURL =
uri"$baseUrl/pet/findByTags"
.addParams(FormSerializable.serialize("tags", tags, FormStyleFormat.FORM, false): _*)
+ .addParams(FormSerializable.serialize("colors", colors, FormStyleFormat.FORM, false): _*)
+ .addParams(FormSerializable.serialize("uniqueTags", uniqueTags, FormStyleFormat.FORM, true): _*)
</file context>
There was a problem hiding this comment.
Note: this empty-collection behavior is pre-existing, not introduced by this PR. The explode=false branch of serializeArray has always emitted name= for an empty collection (Seq(paramName -> values.map(_.asString).mkString(",")) with no empty guard), and it's shipped on master in the primitive Seq path since before the enum-array and Set work — so it already affects existing array params like status/tags, not just the new Set params. This change fixes it at the source (serializeArray), making explode=false consistent with explode=true, which already omits empty collections.
…n instead of emitting name=
An empty array/set parameter with explode=false previously serialized as `name=`
rather than being omitted, unlike explode=true which already dropped it. For an
optional collection an empty value means "not provided" and should not appear in
the request. Guard serializeArray so an empty collection yields no entries,
making explode=false consistent with explode=true.
|
Thanks for the PR, which has been merged FYI @clasnake (2017/07), @shijinkui (2018/01), @ramzimaalej (2018/03), @chameleon82 (2020/03), @Bouillie (2020/04) @Fish86 (2023/06) |
Parameters whose schema has
uniqueItems: trueare generated as ScalaSet, but the serializers only matchedSeq, so anySetparameter — includingSet[String]— failed to compile with aMirror.Of[Set[...]]error. This predates the enum-array work;Setwas never handled.Add
Set[p]/Option[Set[p]]cases to FormSerializable, HeaderSerializable, PathSerializable and CookieSerializable. BecauseSetis invariant (unlike the covariantSeq), the element type is bound and dispatched on viaerasedValue: primitives and enums both convert toSeqand reuse the existing array serialization, so all style/explode combinations keep working. Non-enum, non-primitive element types fail with a clear compile-time error.Extend the sample spec with a
Setof referenced enums (colors/PetColor) and aSetof primitives (uniqueTags) so the samples build exercises both paths.PR checklist
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.
Summary by cubic
Support
Set[...]parameters inscala-sttp4-jsoniteracross query, header, path, and cookie, and fix form serialization to omit empty arrays/sets. This unblocks uniqueItems arrays generated as Scala sets and avoids emitting empty param entries.Set[p]andOption[Set[p]]handling to Form, Header, Path, and Cookie serializers; supports primitives and referenced enums, with unsupported element types failing at compile time.explode=false(noname=), matchingexplode=trueand optional semantics. Updated samples/spec to cover sets: addedPetColorenum anduniqueTags, and extendedfindPetsByTagswithcolors: Set[PetColor]anduniqueTags: Set[String].Written for commit 19350b7. Summary will update on new commits.