Подтвердить что ты не робот

Как я могу реализовать этот запрос POST с помощью HTTParty?

У меня возникли трудности с отправкой запроса POST в конечную точку API с использованием библиотеки Ruby HTTParty. API, с которым я взаимодействую, это Gittip API, и их конечная точка требует аутентификации. Я смог успешно выполнить аутентифицированный запрос GET с помощью HTTParty.

В примере кода вы можете увидеть:

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

Этот запрос работает и возвращает следующее, как ожидалось:

[
  {
    "amount" => "1.00",
    "platform" => "gittip",
    "username" => "whit537"
  },
  {
    "amount" => "0.25",
    "platform" => "gittip",
    "username" => "JohnKellyFerguson"
  }
]

Однако я не смог выполнить успешный запрос POST с использованием HTTParty. API Gittip описывает запрос POST с использованием curl следующим образом:

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"

Я попытался (неудачно) структурировать свой код с помощью HTTParty следующим образом:

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

Первым аргументом является url, а второй аргумент - хэш параметров. Когда я запускаю код выше, я получаю следующую ошибку:

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'

Я пробовал другие комбинации структурирования вызова API, но не могу понять, как заставить его работать. Вот еще один такой пример, где я не являюсь пользователем массивом как частью тела и конвертирует содержимое 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' }
           })

Что возвращает следующее (ошибка 500):

<html>
  <head>
    <title>500 Internal Server Error</title>
  </head>
  <body>\n        Internal server error, program!\n        <pre></pre>  
  </body>
</html>

Я не очень хорошо разбираюсь в завитках, поэтому не уверен, что я неправильно перевел вещи на HTTParty.

Любая помощь будет оценена по достоинству. Спасибо.

4b9b3361

Ответ 1

Просто догадайтесь, но похоже, что вы передаете хэш в теле, когда ожидается JSON.

Попробуйте заменить объявление :body на:

:body => [{ "amount" => "0.25", 
             "platform" => "gittip", 
             "username" => "whit537" }].to_json

Изменить: Я предложил сериализатор to_json, но упустил его, поставив его после хэша вместо массива и полностью удалив массив. В примере используется несколько записей, поэтому массив необходим.

Посмотрев этот поток, похоже, что Gittip придирчив к заголовку accept.

:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}

Итак, полное предложение:

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