Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grape, sending JSON as params

My Grape API accepts json format and I have method that accepts JSON as parameter:

desc 'JSON test'
params do
  requires :json, type: JSON
end
post :json_test do
  json = params[:json]
  {result: json}
end

When I make request via postman, parameters are raw with application/json content type:

{
   "json": {"test": "test"}
}

When I send this I get error message:

"json is invalid"

However, when I send it like this:

{
  "json": "{\"test\": \"test\"}"
}

It shows me correct response:

{
 "result": {
   "test": "test"
  }
}

Why this is happening? When I make type Hash the first variant works, but if I want to send Array of hashes/jsons? I kniw that Grape does not support Array[Hash] type.

like image 358
Mr.D Avatar asked Feb 08 '23 05:02

Mr.D


2 Answers

grape parses the application/json data before it reaches your params block.


in this block:

params do
  requires :json, type: JSON
end

you are telling grape that your :json param should contain a JSON string.

so when you send this:

{
   "json": {"test": "test"}
}

json contains

{"test": "test"} 

which is sees as a hash, not a valid JSON string hence our error.

but when you send this

{
  "json": "{\"test\": \"test\"}"
}

json contains

"{\"test\": \"test\"}"

which is a valid JSON string, which it will then happily parse into a hash for you.


If you want to use

{
   "json": {"test": "test"}
}

in your post request, Your params block should be something like this:

params do
    requires :json, type: Hash #<-- Hash here instead of JSON since json data has already been parsed into a Hash
end
like image 109
KorreyD Avatar answered Feb 11 '23 00:02

KorreyD


If you want to parse a classic JSON with Grape using this:

params do
  requires :groceries, type: JSON
end

then send a JSON with a single key, that has a value of type String (a JSON String).

Examples for sending the JSON:

Use as raw parameter:

{ "groceries_key": "{\"fruits\": { \"apples\": 2 }, \"vegetables\": { \"carrets\": \"a few\" }}" }

Use in a HTTP GET request:

http://localhost/api/test?groceries=<the_above_raw_parameter_without_whitespaces>

Examples for parsing the JSON:

The value is a JSON String, and to parse it, use

get do    
  JSON.parse (params['groceries']['groceries_key'])
end

which will give you a nice json:

{
  "fruits": {
    "apples": 2
  },
  "vegetables": {
    "carrets": "a few"
  }
}

versions used:

gem 'grape',         '0.14.0'
gem 'grape-swagger', '0.20.2'
ruby 1.9.3p545
like image 45
Yair Segal Avatar answered Feb 11 '23 01:02

Yair Segal