Question

I have two rails services. One serving the UI and some basic functionality (UIService) and another which manages the underlying models and database interactions (MainService).

At the UIService, I have a form that collects a list of items and uses that to POST to MainService via jQuery.

I take the javascript array and call the jQuery.post to UIService first, like this -

var selected_items = new Array();
// Filled up via the form...
params={"name":$("#name_input").val(),
        "items": selected_items };
jQuery.post("/items", params);

This is then converted to an array of hashes with the key "item_id" and then forwarded to the MainService via Typhoeus like this -

items = []
item = {}
params[:items].each do |i|
  item[:item_id] = i
end
## Gives me this ---> items = [ {item_id: 189}, {item_id: 187} ]

req = Typhoeus::Request.new("#{my_url}/items/", 
                            method: :POST, 
                            headers: {"Accepts" => "application/json"})
hydra = Typhoeus::Hydra.new
hydra.queue(req)
hydra.run

At the MainService, I need the JSON schema to be in a particular format. Basically an array of items... like this -

{ "name": "test_items", "items": [ {"item_id":"189"},{"item_id": "187"} ] }

The issue is that when I collect the array from jQuery and pass it to UIService, it looks like this in the params -

[ {item_id: 189}, {item_id: 187} ]

But, when it arrives at MainService, it becomes this -

{"name"=>"test_items",
 "items"=>{"0"=>{"item_id"=>"189"}, "1"=>{"item_id"=>"187"}}

So, I need the array of items to be key'ed with "item_id" and inserted into the params. I tried several ways to keep it as an array of hashes, but it always ends up in the wrong format at the destination.

I tried various workarounds, like stringifying, not stringifying, building my own array of hashes etc. I'm pretty stuck at this point. Any ideas? Anything I'm doing wrong or not doing? I can make it work other JSON schemas, but I need to stick to this one.

Was it helpful?

Solution

The issue was with the way I was passing the parameters into typhoeus

before (with issue) --

req = Typhoeus::Request.new("#{Rails.application.config.custom_ads_url}/groups", 
                            method: :POST,
                            params: parameters,
                            headers: {"Content-Type" => "application/json",     "AUTHORIZATION" => "auth_token #{user.auth_token}"})

after (works) -- notice that I needed to convert to json and put it in the body. 'params' in typhoeus was being considered as a custom hash.

req = Typhoeus::Request.new("#{Rails.application.config.custom_ads_url}/groups", 
                            method: :POST,
                            body: parameters.to_json,
                            headers: {"Content-Type" => "application/json", "AUTHORIZATION" => "auth_token #{user.auth_token}"})

OTHER TIPS

There is also a middleware provided by Typhoeus which does the correct conversion: http://rubydoc.info/github/typhoeus/typhoeus/frames/Rack/Typhoeus/Middleware/ParamsDecoder.

If you're using the Typhoeus class method .post you can implement your request like so:

Typhoeus.post(
  "#{Rails.application.config.custom_ads_url}/groups",
  headers: { 'Content-Type'=> "application/json" },
  body: parameters.to_json
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top