Search code examples
ruby-grapegrape-api

How do I map the JSON body of a GET request to a parameter?


I have the following definition in my endpoint:

params do
    requires :entities do
      requires :id, type: String
      optional :email, type: String
      optional :phone, type: String
    end
  end
  post "test" do

  end

Note this only works as a POST request and the following CURL will work:

curl -XPOST localhost/test 
     -H 'Content-Type: application/json' 
     -H 'Accept: application/json' 
     -d '{ "entities": [{ "id": 3, "email": "[email protected]" }] }'

However, the moment I change the declaration to get "test" instead of post, the corresponding curl request with -XGET no longer works due to the following validation error:

{"error":"entities is missing"}

If I remove the params requirements I can manually inspect the params hash at runtime and see that it only has a single key "route_info"

I'm currently using Grape 0.7.0


Solution

  • It happens because by specifying -d option you pass parameters in the body of the request while your endpoint is expecting them in the path as part of the url. Check here why it's a bad idea to pass body parameters in a GET request.

    However, can use that option but if combination with -G.

    -G, --get

    When used, this option will make all data specified with -d, --data, --data-binary or --data-urlencode to be used in an HTTP GET request instead of the POST request that otherwise would be used. The data will be appended to the URL with a '?' separator.

    So that your get request by using -d would look like:

    curl -XGET -G localhost/test 
         -H 'Content-Type: application/json' 
         -H 'Accept: application/json' 
         -d '{ "entities": [{ "id": 3, "email": "[email protected]" }] }'