Skip to content

HashConversions does not handle objects with varying keys in arrays #719

@twelve17

Description

@twelve17

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? 😉

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions