Skip to content

Allow customizing default query encoder#145

Merged
mromaszewicz merged 1 commit into
oapi-codegen:mainfrom
mromaszewicz:fix/issue-2051
Jul 15, 2026
Merged

Allow customizing default query encoder#145
mromaszewicz merged 1 commit into
oapi-codegen:mainfrom
mromaszewicz:fix/issue-2051

Conversation

@mromaszewicz

Copy link
Copy Markdown
Member

Addresses oapi-codegen/oapi-codegen#2051

Go's net/url encodes a space in query strings as '+' (the form-urlencoded convention), which is not RFC 3986 compliant. Some servers (e.g. OData endpoints expecting ?filter=name%20eq%20'x') reject '+'-encoded spaces with 400 Bad Request, while others require '+'. Since neither encoding is universally correct, this makes the behavior configurable rather than changing the default.

Introduce a QueryEncoder interface with two built-in implementations in a new encoder.go: NetURLQueryEncoder (the default, '+' for space, preserving current behavior) and RFC3986QueryEncoder ('%20' for space). A package-level DefaultQueryEncoder (mirroring http.DefaultClient) lets callers opt in during program initialization.

All query escaping in styleparam.go and deepobject.go now routes through DefaultQueryEncoder, so both styled and deepObject query parameters honor the choice. Path escaping and x-www-form-urlencoded request bodies are left unchanged, where '+' for a space is the correct, media-type-defined behavior.

Documented under the README "Encoding" section; tests in encoder_test.go.

@mromaszewicz mromaszewicz requested a review from a team as a code owner July 15, 2026 04:21
@mromaszewicz mromaszewicz added the enhancement New feature or request label Jul 15, 2026
Addresses oapi-codegen/oapi-codegen#2051

Go's net/url encodes a space in query strings as '+' (the form-urlencoded
convention), which is not RFC 3986 compliant. Some servers (e.g. OData
endpoints expecting ?filter=name%20eq%20'x') reject '+'-encoded spaces with
400 Bad Request, while others require '+'. Since neither encoding is
universally correct, this makes the behavior configurable rather than
changing the default.

Introduce a QueryEncoder interface (a single EscapeQueryValue method) with two
built-in implementations in a new encoder.go: NetURLQueryEncoder (the default,
'+' for space, preserving current behavior) and RFC3986QueryEncoder ('%20' for
space). A package-level DefaultQueryEncoder (mirroring http.DefaultClient) lets
callers opt in during program initialization. Names and map keys are escaped as
values with allowReserved=false, which allowReserved never applies to.

All query escaping in styleparam.go and deepobject.go now routes through
DefaultQueryEncoder, so both styled and deepObject query parameters honor the
choice. Path escaping and x-www-form-urlencoded request bodies are left
unchanged, where '+' for a space is the correct, media-type-defined behavior.

Documented under the README "Encoding" section; tests in encoder_test.go.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mromaszewicz mromaszewicz merged commit 1463938 into oapi-codegen:main Jul 15, 2026
11 checks passed
@mromaszewicz mromaszewicz deleted the fix/issue-2051 branch July 15, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant