Skip to content

fix(analyzer): a parameter serialized with content went out style-encoded - #82

Merged
giraffesyo merged 1 commit into
canaryfrom
content-params
Aug 20, 2026
Merged

fix(analyzer): a parameter serialized with content went out style-encoded#82
giraffesyo merged 1 commit into
canaryfrom
content-params

Conversation

@giraffesyo

Copy link
Copy Markdown
Member

Closes #77.

parameters:
  - name: filter
    in: query
    content:
      application/json:
        schema: { $ref: "#/components/schemas/Filter" }

convertParam read only param.Schema and never looked at param.Content, so the parameter lost its type and was encoded with the form style:

type ListItemsParams struct {
	Filter *any `json:"filter,omitempty"`   // before
}

addQueryParam(queryValues, "filter", "form", true, params.Filter)

Not merely awkward: a struct handed to the style encoder does not come out as the JSON document the server is parsing, so the request was wrong on the wire.

Now

type ListItemsParams struct {
	Filter *Filter `json:"filter,omitempty"`
}

addContentQueryParam(queryValues, "filter", params.Filter)

The value is serialized as the media type it declares, then percent-encoded into the query. Header and cookie parameters get the same treatment through setContentHeader and addContentCookieHeader.

With #80 merged, the schema behind a content parameter is typed even when written inline, so content: {application/json: {schema: {type: object, ...}}} yields a real struct rather than any. There is a test for that composition.

Decisions

  • Only media types the generator can write are serialized. An application/xml content parameter keeps today's style encoding and warns, rather than sending JSON where the server expects something else:

    warning: parameter "legacy": application/xml is not a media type this generator serializes, so the value is sent style-encoded
    

    The warning rides the pkg.Warnings channel from fix(analyzer): a security scheme the generator cannot use costs the whole client #64, now also fed from an analyzer-level buffer.

  • No name hint on the schema branch. Passing one there types inline unions and objects in style-encoded parameters, which sounds like an improvement and is not: the query encoder writes a synthesized union out as its Go shape (value=...) rather than as the value the server parses. TestNullableUnion_QueryParamsResolveToTheVariantType caught it. Typed union parameters need the encoder to understand them first, which is separate work.

Tests

  • internal/analyzer/operations_test.go: the media type and its schema reach the IR, a style parameter carries no content type, and an unserializable media type produces exactly one warning naming the parameter.
  • internal/generator/e2e_content_param_test.go: compiles and runs against httptest, decoding the query parameter and the header back into the declared type, checking an inline schema is typed and serialized, that a style parameter beside it still goes out unquoted, and that an omitted optional parameter sends nothing rather than null.

gofmt, go vet ./..., and go test ./... pass.

…oded

A parameter that names a media type instead of a style carries a document,
and the media type says how to serialize it. convertParam read only
param.Schema, so the value lost its type and was then encoded with the form
style, which is not what the server parses.

The media type's schema now types the parameter, and a JSON one is written
as the document it declares before being percent-encoded into the query,
set as a header value, or written into a cookie. Anything the generator
cannot write, XML among others, warns and keeps today's encoding rather
than sending JSON where the server expects something else.

The name hint stays off the schema branch on purpose: a style-encoded
parameter is written into the URL by the query encoder, and a synthesized
union or struct there would go out as its Go shape rather than as the value
the server parses.
@giraffesyo
giraffesyo merged commit 9925271 into canary Aug 20, 2026
7 checks passed
@giraffesyo
giraffesyo deleted the content-params branch August 20, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A parameter serialized with content becomes *any and is sent form-encoded

1 participant