Repository navigation
Commit a61e05c
[go] fix: explode object query parameters (#24797)
* fix: [go] explode object query parameters
A query parameter whose schema is an object and whose style/explode are left at
their defaults — style: form, explode: true — must go on the wire as one
parameter per entry, keyed by the property name alone. The go client bracketed
it as filter[category]=books instead.
parameterAddToHeaderOrQuery in go/client.mustache bracketed every map whatever
style it was handed. The reflect.Slice case immediately above it already
branches on style == "deepObject", so the map case looks like an oversight. The
generated api passes the style correctly; nothing downstream read it.
The flattening applies to the top level only. The recursive call no longer
carries the style down, so anything nested inside an entry keeps the path it has
accumulated: {profile: {name: "x"}} is profile[name]=x, and two siblings holding
the same property name stay distinct — {a: {x: 1}, b: {x: 2}} is a[x]=1&b[x]=2
rather than a pair of colliding x= entries. Nested slices are unaffected, since
the slice branch only special cases deepObject and so behaves identically for an
empty style and for form.
* fix: [go] an array element does not inherit the form flattening
A form style query parameter whose value is an array of maps reached the
map branch one level down with the style still set, so the entries were
keyed by their property names alone and the accumulated parent path was
dropped. Reset the style when descending into array elements, mirroring
the reset the map branch already does for its entries: only a map that is
the parameter's direct value is exploded to bare property names.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Go3AyndcGwv5tFTwo9aBfy
* test: [go] cover the array of objects the element reset exists for
The fixture declared four object parameters and no array, so the
assertions added for the element reset in 470b7e0 only matched template
text that every generated client.go carries: they held whatever the
fixture contained.
Add the array of objects, and deliberately not exploded. That is the
only shape that reaches the array branch of parameterAddToHeaderOrQuery:
with explode: true the api template unrolls the slice itself and hands
each element over as a map, which enters the map branch instead, so an
exploded array would have left the branch as uncovered as no array at
all. Not exploded, the whole slice arrives as one form style value:
parameterAddToHeaderOrQuery(localVarQueryParams, "arrayFilter", r.arrayFilter, "form", "csv")
which is asserted, and is derived from the spec rather than from the
template.
The behaviour itself lives in generated go rather than in the generator,
so it is not reachable from a codegen test. Exercising the helper in a
generated client directly, with a []map[string]interface{} under style
form: filter[a]=1 with the reset, a=1 without it, while a map that is
the parameter's own value stays a=1 either way.
mvn -pl modules/openapi-generator -Dtest=GoClientCodegenTest test:
28 tests, 0 failures.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01894FEkx3sDA5wTqjeEo33D
* chore: [go] drop the stray go.mod and go.sum changes
Running the go toolchain in the issue_20079_go_regex_wrongly_translated
sample rewrote its go.mod and go.sum, and the rewrite was swept into the
array element commit. bin/generate-samples.sh emits neither, so the
samples up to date job reverted both files and failed on the dirty tree.
Restore them to what the generator produces.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JHEXQ9zWNyGwVnWPJJnzSo
* fix: [go] skip nil entries of an exploded object query parameter
A nil entry of a form style exploded map went on the wire as the literal
"null" (nullValue=null), and so did a nil element of a list an entry
holds (anyList=x&anyList=null&anyList=2). Both are now left out, after
unwrapping interfaces and pointers, matching the kotlin port.
A typed nil pointer, such as (*string)(nil), panicked with
"reflect.Value.Interface on zero Value" because the pointer branch called
Elem().Interface() without a nil check. It is now left out as well; that
branch is shared with deepObject, where it turns the same panic into an
omitted value. deepObject is otherwise unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: [go] skip nil entries under deepObject too
The previous commit left nil entries out of a form style exploded map but
not out of a deepObject one, so the same map went on the wire two ways: a
nil entry was dropped under form and sent as filter[k]=null under
deepObject. deepObject was also inconsistent with itself, because the nil
check added to the pointer branch already dropped a typed nil pointer
there.
Move the entry check ahead of the form branch, so it applies whatever the
style, and skip a nil element in the array branch as well. The elements
that survive keep the index they had, so filter[l][0] and filter[l][2]
stay where they are rather than closing the gap; the index names a
position in the array the caller passed, and renumbering would quietly
move the remaining values.
Nothing changes for a non-nil value, and a nil parameter passed at the
top level still goes out as key=null.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* revert: [go] keep deepObject's null for a nil entry
This reverts cd901bc. deepObject sending [key]=null for a nil entry is
behaviour the petstore sample pins in TestQueryDeepObject, and it is the same
on master, so it stays out of a change about form style. Form style keeps
skipping nil entries, and the nil check in the pointer case stays.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test: [go] pin the nil-entry skip inside the form branch
The assertion on parameterValueIndirect alone also matched the reverted
layout that skipped nil for every style. Pinning what follows the skip
fails if it is ever moved ahead of the style branch again, which would
break deepObject's [key]=null that TestQueryDeepObject expects.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: [go] trim the exploded object comments, test and fixture
The shipped comments shrink to one line each, parameterValueIndirect
returns true once it has unwrapped a non-nil value, the codegen test
keeps only the assertions that fail without each fix, and arrayFilter
leaves the shared fixture so it is byte-identical across the ports again.
The fixture's description now names the three combinations it covers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: [go] keep the validity check in parameterValueIndirect
The constant true reported an invalid reflect.Value as usable. No caller
passes one today, but the check guards v.Interface() against a panic and
costs nothing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent da04b93 commit a61e05c
14 files changed
Lines changed: 562 additions & 26 deletions
File tree
- modules/openapi-generator/src
- main/resources/go
- test/java/org/openapitools/codegen/go
- samples
- client
- echo_api
- go-external-refs
- go
- others/go
- allof_multiple_ref_and_discriminator
- issue_20079_go_regex_wrongly_translated
- oneof-anyof-required
- oneof-discriminator-lookup
- petstore/go/go-petstore
- openapi3/client
- extensions/x-auth-id-alias/go-experimental
- petstore
- go-petstore-generateMarshalJSON-false
- go-petstore-withXml
- go
- go-petstore-aws-signature
- go-petstore
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
| 194 | + | |
194 | 195 | | |
195 | 196 | | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
196 | 200 | | |
197 | | - | |
| 201 | + | |
198 | 202 | | |
199 | 203 | | |
200 | 204 | | |
| |||
206 | 210 | | |
207 | 211 | | |
208 | 212 | | |
209 | | - | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
210 | 234 | | |
211 | 235 | | |
212 | 236 | | |
213 | 237 | | |
214 | 238 | | |
215 | 239 | | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
216 | 243 | | |
217 | 244 | | |
218 | 245 | | |
| |||
247 | 274 | | |
248 | 275 | | |
249 | 276 | | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
250 | 289 | | |
251 | 290 | | |
252 | 291 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
144 | 173 | | |
145 | 174 | | |
146 | 175 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments