Priority: P1
Describe the issue
The query: and URL-encoded form: options currently accept only a map whose values are scalar booleans, platform-sized integers, floats, or strings. They reject both common Ruby representations of repeated fields:
- a hash with an array value; and
- an enumerable of key-value pairs.
Repeated keys are ordinary HTTP API input (tag=a&tag=b, facets, filters, and multi-select fields). An ordered pair list is also needed when duplicate keys or exact field order must be preserved.
Reproduction
Tested with wreq 1.2.4:
require "wreq"
client = Wreq::Client.new
client.get("https://example.com", query: {tag: %w[ruby http]})
# RuntimeError: data did not match any variant of untagged enum ParamValue
client.get(
"https://example.com",
query: [["tag", "ruby"], ["tag", "http"]]
)
# TypeError: expected a map, got sequence
client.get("https://example.com", query: {id: 2**63})
# RangeError: bignum too big to convert into `long long'
The equivalent shapes fail for form: as well.
Proposed Ruby API
Keep query: and form: for compatibility, but accept the same two shapes as Ruby's URL-encoding APIs:
client.get(
"https://example.com/search",
query: {tag: %w[ruby http], page: 2}
)
# GET /search?tag=ruby&tag=http&page=2
client.post(
"https://example.com/search",
form: [
[:tag, "ruby"],
[:tag, "http"],
[:page, 2]
]
)
# body: tag=ruby&tag=http&page=2
Encoding semantics
- Hash array values expand to one field per element.
- Enumerable pairs preserve input order and duplicate keys.
- String and Symbol keys are accepted and encoded by their string value.
- Scalar String, Symbol, Integer, Float, boolean, and
nil values follow documented URI.encode_www_form-compatible conversion. Ruby Integers are stringified without narrowing to the native platform integer range.
- Invalid pair shapes raise
ArgumentError before network I/O.
- This issue covers
application/x-www-form-urlencoded data only. Multipart file uploads remain tracked by #86.
Acceptance criteria
- Both options accept a Hash and an enumerable of pairs.
- Duplicate keys reach the wire without being collapsed.
- Pair order is stable.
- Hash array values produce repeated fields.
- Existing scalar hashes remain backward compatible.
- Tests cover spaces, Unicode, reserved characters, blank strings,
nil, booleans, arbitrary-precision Integers, duplicate keys, array values, and invalid entries for both query and form encoding.
Ruby ecosystem precedent
- Ruby's
URI.encode_www_form accepts any enumerable, accepts hashes, expands array values into repeated keys, and preserves enumerable order.
HTTPX::Request accepts hashes or arrays of key-value pairs for query and form parameters.
Net::HTTPHeader#set_form accepts hash and pair-list form data.
wreq-python accepts mappings or ordered sequences of pairs for query and form input over the same Rust client. Ruby array-value expansion remains a Ruby-specific URI.encode_www_form convention.
Relevant wreq-ruby source
Priority: P1
Describe the issue
The
query:and URL-encodedform:options currently accept only a map whose values are scalar booleans, platform-sized integers, floats, or strings. They reject both common Ruby representations of repeated fields:Repeated keys are ordinary HTTP API input (
tag=a&tag=b, facets, filters, and multi-select fields). An ordered pair list is also needed when duplicate keys or exact field order must be preserved.Reproduction
Tested with wreq 1.2.4:
The equivalent shapes fail for
form:as well.Proposed Ruby API
Keep
query:andform:for compatibility, but accept the same two shapes as Ruby's URL-encoding APIs:Encoding semantics
nilvalues follow documentedURI.encode_www_form-compatible conversion. Ruby Integers are stringified without narrowing to the native platform integer range.ArgumentErrorbefore network I/O.application/x-www-form-urlencodeddata only. Multipart file uploads remain tracked by #86.Acceptance criteria
nil, booleans, arbitrary-precision Integers, duplicate keys, array values, and invalid entries for both query and form encoding.Ruby ecosystem precedent
URI.encode_www_formaccepts any enumerable, accepts hashes, expands array values into repeated keys, and preserves enumerable order.HTTPX::Requestaccepts hashes or arrays of key-value pairs for query and form parameters.Net::HTTPHeader#set_formaccepts hash and pair-list form data.wreq-pythonaccepts mappings or ordered sequences of pairs for query and form input over the same Rust client. Ruby array-value expansion remains a Ruby-specificURI.encode_www_formconvention.Relevant wreq-ruby source
src/client/param.rssrc/client/query.rssrc/client/body/form.rs