-
Notifications
You must be signed in to change notification settings - Fork 970
Description
Using a variant of the example in HashConversions, given object obj:
{
"name": "Bob",
"phones": [
{
"type": "home" // He finally cut the cord!
},
{
"type": "work",
"phone": "333-333-3333"
}
]
}
The following params are produced by to_params:
[51] pry> params = HTTParty::HashConversions.to_params(obj)
=> "name=Bob&phones%5B%5D%5Btype%5D=home&phones%5B%5D%5Btype%5D=work&phones%5B%5D%5Bphone%5D=333-333-3333"
[52] pry>)> puts JSON.pretty_generate(CGI.parse(params))
{
"name": [
"Bob"
],
"phones[][type]": [
"home",
"work"
],
"phones[][phone]": [
"333-333-3333"
]
}
Bob's work phone number is now his home number.
I realize working around this would require inspecting all array entries and compiling a superset of all keys.
Perhaps the bigger issue I'm seeing is that the default behavior of HTTParty.post when body is an object is to delegate to non-standard serialization of the object, versus assuming the caller wants to send JSON (and thus switch to Content-type: application/json).
Since serialization of array query parameters do not seem to have an agreed-to standard, it would seem more sensical to have this be an opt-in code path, and the default be the JSON code path. Especially when you consider the ambiguous format: :json parameter:
HTTParty.post(
"/some/url",
format: :json,
body: {
"name: "Bob",
"phones": [
{
"type": "home"
},
{
"type": "work",
"phone": "333-333-3333"
}
]
}
)
The combination of format: :json and passing of an object to the body really kinda makes this request seem like it's going to send a JSON payload. But to the unsuspecting eye, it can inadvertently lead to a lot of Bobs getting their work calls at home.
Of course, if you RTFM, you'll understand that format: :json only applies to the request, but "Hey, RTFM" sounds like the kind of thing someone might respond to with "You must be fun at parties". And well, this is a HTTParty, right? 😉