I am having difficulty making a POST request to an API endpoint using Ruby's HTTParty library. The API I'm interacting with is the Gittip API and their endpoint requires authentication. I have been able to successfully make an authenticated GET request using HTTParty.
You can see in the example code:
user = "gratitude_test"
api_key = "5962b93a-5bf7-4cb6-ae6f-aa4114c5e4f2"
# I have included real credentials since the above is merely a test account.
HTTParty.get("https://www.gittip.com/#{user}/tips.json",
{ :basic_auth => { :username => api_key } })
That request works and returns the following as expected:
[
{
"amount" => "1.00",
"platform" => "gittip",
"username" => "whit537"
},
{
"amount" => "0.25",
"platform" => "gittip",
"username" => "JohnKellyFerguson"
}
]
However, I have been unable to make a successful POST request using HTTParty. The Gittip API describes making a POST request using curl as follows:
curl https://www.gittip.com/foobar/tips.json \
-u API_KEY: \
-X POST \
-d'[{"username":"bazbuz", "platform":"gittip", "amount": "1.00"}]' \
-H"Content-Type: application/json"
I have tried (unsuccessfully) structuring my code using HTTParty as follows:
user = "gratitude_test"
api_key = "5962b93a-5bf7-4cb6-ae6f-aa4114c5e4f2"
HTTParty.post("https://www.gittip.com/#{user}/tips.json",
{
:body => [ { "amount" => "0.25", "platform" => "gittip", "username" => "whit537" } ],
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json' }
})
The first argument is the url and the second argument is an options hash. When I run the code above, I get the following error:
NoMethodError: undefined method `bytesize' for [{"amount"=>"0.25", "platform"=>"gittip", "username"=>"whit537"}]:Array
from /Users/John/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http/generic_request.rb:179:in `send_request_with_body'
I have tried various other combinations of structuring the API call, but can't figure out how to get it to work. Here's another such example, where I do not user an array as part of the body and convert the contents to_json
.
user = "gratitude_test"
api_key = "5962b93a-5bf7-4cb6-ae6f-aa4114c5e4f2"
HTTParty.post("https://www.gittip.com/#{user}/tips.json",
{
:body => { "amount" => "0.25", "platform" => "gittip", "username" => "whit537" }.to_json,
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json' }
})
Which returns the following (a 500 error):
<html>
<head>
<title>500 Internal Server Error</title>
</head>
<body>\n Internal server error, program!\n <pre></pre>
</body>
</html>
I'm not really familiar with curl, so I'm not sure if I am incorrectly translating things to HTTParty.
Any help would be appreciated. Thanks.
Just a guess, but it looks like you're passing a hash in the body when JSON is expected.
Try replacing the :body
declaration with:
:body => [{ "amount" => "0.25",
"platform" => "gittip",
"username" => "whit537" }].to_json
Edit:
I suggested the to_json
serializer, but misplaced it by putting it after the hash instead of the array and removing the array altogether. The example uses multiple records, so the array is necessary.
After looking at this thread, it looks like Gittip is picky about the accept header.
:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
So, the full suggestion is:
HTTParty.post("https://www.gittip.com/#{user}/tips.json",
{
:body => [ { "amount" => "0.25", "platform" => "gittip", "username" => "whit537" } ].to_json,
:basic_auth => { :username => api_key },
:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
})