Forum: Ruby on Rails Request with Content-Type: "application/json" add extra parameter.

85aefb70456b4ed1e73c91a4b400be5b?d=identicon&s=25 unknown (Guest)
on 2013-04-18 09:07
(Received via mailing list)
Howdy,

I am making a few AJAX endpoints using rails, and noticed the following
inconsistent behavior when setting the Content-Type to application/json.
 Here are four different requests to show the problem I am having.

1. First, when I make the following example request:

curl -X GET
"http://localhost:3000/api/v1/events?counts=true&or...

Rails shows the following in the log:

Started GET
"/api/v1/events?counts=true&order%5Bcolumn%5D=occurs_at&order%5Bdirection%5D=asc&page%5Bnumber%5D=1&page%5Blimit%5D=100"
for 127.0.0.1 at 2013-04-18 03:57:49 +0000
Processing by Api::V1::EventsController#index as JSON
  Parameters: {"counts"=>"true", "order"=>{"column"=>"occurs_at",
"direction"=>"asc"}, "page"=>{"number"=>"1", "limit"=>"100"}}

2. However, if I change the Content-Type to be "application/json":

curl -X GET -H "Content-Type: application/json"
"http://localhost:3000/api/v1/events?counts=true&or...

I get the following:

Started GET
"/api/v1/events?counts=true&order%5Bcolumn%5D=occurs_at&order%5Bdirection%5D=asc&page%5Bnumber%5D=1&page%5Blimit%5D=100"
for 127.0.0.1 at 2013-04-18 03:57:33 +0000
Processing by Api::V1::EventsController#index as JSON
  Parameters: {"counts"=>"true", "order"=>{"column"=>"occurs_at",
"direction"=>"asc"}, "page"=>{"number"=>"1", "limit"=>"100"},
*"event"=>{}*}

The bold part is the extra parameter (in this case "event") that gets
added
by making this a JSON request.

3. The problem, is that this event parameter will clobber any parameter
I
send over also called event.  For example:

curl -X GET -H "Content-Type: application/json"
"http://localhost:3000/api/v1/events?counts=true&or...
*event=Super%20Important%20Info*"

And it is not parsed from the params:

Started GET
"/api/v1/events?counts=true&order%5Bcolumn%5D=occurs_at&order%5Bdirection%5D=asc&page%5Bnumber%5D=1&page%5Blimit%5D=100&
*event=Super%20Important%20Info*" for 127.0.0.1 at 2013-04-18 04:02:56
+0000
Processing by Api::V1::EventsController#index as JSON
  Parameters: {"counts"=>"true", "order"=>{"column"=>"occurs_at",
"direction"=>"asc"}, "page"=>{"number"=>"1", "limit"=>"100"},
*"event"=>{}*}

4. But, if I dont pass the JSON content type:

curl -X GET
"http://localhost:3000/api/v1/events?counts=true&or...
*event=Super%20Important%20Info*"

It works just fine:

Started GET
"/api/v1/events?counts=true&order%5Bcolumn%5D=occurs_at&order%5Bdirection%5D=asc&page%5Bnumber%5D=1&page%5Blimit%5D=100&
*event=Super%20Important%20Info*" for 127.0.0.1 at 2013-04-18 04:02:22
+0000
Processing by Api::V1::EventsController#index as JSON
  Parameters: {"counts"=>"true", "order"=>{"column"=>"occurs_at",
"direction"=>"asc"}, "page"=>{"number"=>"1", "limit"=>"100"},
*"event"=>"Super
Important Info"*}

Is there any way I can just turn off this functionality?  I think it
might
be because this is an EventsController, and Rails is trying to give me
something for free, but I just want to send over whatever I want,
especially as I will have situations like an OrdersController, that I
want
to pass an order to (such as id asc, etc..).

Thanks for any help,

Robert
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2013-04-18 09:26
(Received via mailing list)
On Thursday, April 18, 2013 5:10:14 AM UTC+1, rob...@capansis.com wrote:
> Howdy,
>
>

>
> Is there any way I can just turn off this functionality? I think it might be
because this is an EventsController, and Rails is trying to give me something 
for
free, but I just want to send over whatever I want, especially as I will have
situations like an OrdersController, that I want to pass an order to (such as id
asc, etc..).
>
>

There are 2 things happening. First, by default if the content type is
json then rails assumes that the request body (in your case the empty
string) is json, and will parse it and add it to params.

The second is something called wrap_parameters.
This wraps the parameters from the body in a hash, so if you posted the
document

{"name": "bob"}

To a users controller, instead of polluting the top level parameter
namespace it would set params[:user] to the result of parsing that.

There is an initializer that turns on wrap parameters. You could remove
it and/or only enable it for some controllers.

By default this only happens if the content type is json.

Lastly why are you setting the content type if you're not submitting the
request body (if you're trying to control the format of the response I
find that it's easiest not to mess around with headers and requests
events.json instead)

Fred
85aefb70456b4ed1e73c91a4b400be5b?d=identicon&s=25 unknown (Guest)
on 2013-04-18 21:21
(Received via mailing list)
Hi Frederick,

Thanks for the help, disabling wrap_parameters in my initializer fixed
my
problem.  Reason why I am setting the content type for the GET is just
because I have jQuery to always ask for JSON.  I could probably set it
to
only send the header on POST/PUT requests, but I would still have the
problem were params would get clobbered in my post body anyway.

Really appreciate the help!
944df1102daf8dff2407bf100ba29024?d=identicon&s=25 Trigger Woods (Guest)
on 2014-01-24 22:04
(Received via mailing list)
Is there meaning of adding a check of method type (GET or POST/PUT) to
ParamsWrapper#_wrapper_enabled?

For example:


def _wrapper_enabled?
       return false if request.get?
       ref = request.content_mime_type.try(:ref)
       _wrapper_formats.include?(ref) && _wrapper_key &&
 !request.request_parameters[_wrapper_key]
end
6883e5ef03484d4fcef507d7b4f1d243?d=identicon&s=25 Matt Jones (Guest)
on 2014-01-25 19:18
(Received via mailing list)
On Thursday, 18 April 2013 15:19:09 UTC-4, rob...@capansis.com wrote:
>
> Hi Frederick,
>
> Thanks for the help, disabling wrap_parameters in my initializer fixed my
> problem.  Reason why I am setting the content type for the GET is just
> because I have jQuery to always ask for JSON.  I could probably set it to
> only send the header on POST/PUT requests, but I would still have the
> problem were params would get clobbered in my post body anyway.
>
>
Content-Type specifies what format the *request* is in (the data you are
sending). For GET requests, it's not particularly meaningful - there
isn't
a "request body", so there's nothing to specify the format of.

If you want to specify what format you'd like the *response* in, use the
Accept header.

http://webmasters.stackexchange.com/questions/3121...

--Matt Jones
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.