Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
863 views
in Technique[技术] by (71.8m points)

ruby - How can I implement this POST request using HTTParty?

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>
        Internal server error, program!
        <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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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'}
  })

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...