2010-01-08 6 views
54

Как отправить запрос JSON в ruby? У меня есть объект JSON, но я не думаю, что могу просто сделать .send. Должен ли я иметь javascript для отправки формы?Ruby отправить запрос JSON

Или я могу использовать класс net/http в рубине?

С заголовком - content type = json и body json object?

ответ

6

Простой JSON POST Пример запроса для тех, кто нуждается даже проще, чем то, что Том ссылается на:

require 'net/http' 

uri = URI.parse("http://www.example.com/search.json") 
response = Net::HTTP.post_form(uri, {"search" => "Berlin"}) 
+13

Это выглядит, как она должна работать, но post_form переводит параметры в ключе = значение & ключ = значение?. Если вы хотите сделать POST с телом запроса, установленным в строку JSON, я думаю, вам нужно другое решение. –

+0

Это не работает с глубоко вложенным json. Все, что находится за пределами первого уровня, становится строкой. – neoneye

+0

Достаточно просто выглядеть. Оно работает. Это просто. но для простых вещей, таких как пример, который я дал, он работает нормально – Christoffer

14

HTTParty делает это немного проще, я думаю (и работает с вложенными JSON и т.д., которые Ждут» т, кажется, работают в других примерах, которые я видел

require 'httparty' 
HTTParty.post("http://localhost:3000/api/v1/users", body: {user: {email: '[email protected]', password: 'secret'}}).body 
-2

Вы можете отправить массив данных JSON как это:.

require 'rest_client' 
postData = Net::HTTP.post_form(URI.parse('http://www.xyz.com/api/valueoff'), 
          {'data'=>jsonData}) 

Для этого необходимо иметь драгоценный камень rest_client.

+1

Этот ответ фактически не использует 'rest_client'. –

4

Предполагая, что вы просто хотите быстро & грязного обращенного хэш в JSON, отправить JSON на удаленный хост для тестирования API и анализировать ответ на рубин это, вероятно, самый быстрый способ без привлечения дополнительных драгоценных камней:

JSON.load `curl -H 'Content-Type:application/json' -H 'Accept:application/json' -X POST localhost:3000/simple_api -d '#{message.to_json}'` 

Надеюсь, это само собой разумеется, но не используйте это в производстве. Попробуйте Фарадея камень, Mislav дает убедительные аргументы, почему: http://mislav.uniqpath.com/2011/07/faraday-advanced-http/

+2

Lol, почему все ненавистники? :) Сообщение четко заявляет, что оно не для производства или какой-либо другой серьезной цели, но его самый быстрый способ настроить JSON-апи-вызов, чтобы посмотреть, как работает служба. – bbozo

49
uri = URI('https://myapp.com/api/v1/resource') 
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json') 
req.body = {param1: 'some value', param2: 'some other value'}.to_json 
res = Net::HTTP.start(uri.hostname, uri.port) do |http| 
    http.request(req) 
end 
+5

Мне нравится ваше предложение использовать URI для обработки имени хоста и порта, который в противном случае это довольно утомительно. Но вы забыли установить uri.path в Post.new (...): 'req = Net :: HTTP :: Post.new (uri.path, initheader = {'Content-Type' => 'application/json' }) ' – ArnauOrriols

+0

Простейший, самый чистый ответ. Отлично. – joelc

+1

Чистый и идеальный! – Zeeshan

26
require 'net/http' 
require 'json' 

def create_agent 
    uri = URI('http://api.nsa.gov:1337/agent') 
    http = Net::HTTP.new(uri.host, uri.port) 
    req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json') 
    req.body = {name: 'John Doe', role: 'agent'}.to_json 
    res = http.request(req) 
    puts "response #{res.body}" 
rescue => e 
    puts "failed #{e}" 
end 
+0

Это работает для меня! – Pred

+0

Какое исключение должно быть указано – Mio

+3

Для запросов https просто добавьте: http.use_ssl = true. –

0

Сеть/HTTP API может быть жестким, чтобы использовать.

require "net/http" 

uri = URI.parse(uri) 

Net::HTTP.new(uri.host, uri.port).start do |client| 
    request     = Net::HTTP::Post.new(uri.path) 
    request.body   = "{}" 
    request["Content-Type"] = "application/json" 
    client.request(request) 
end 
+0

Этот код не работает. Вам нужно инициализировать Net :: HTTP с помощью #start следующим образом: 'Net :: HTTP.start (uri.host, uri.port,: use_ssl => true) do | client |' – Tyler

1

Мне нравится этот свет клиента запрос веса HTTP под названием `unirest»

gem install unirest

использование:

response = Unirest.post "http://httpbin.org/post", 
         headers:{ "Accept" => "application/json" }, 
         parameters:{ :age => 23, :foo => "bar" } 

response.code # Status code 
response.headers # Response headers 
response.body # Parsed body 
response.raw_body # Unparsed body 
0
data = {a: {b: [1, 2]}}.to_json 
uri = URI 'https://myapp.com/api/v1/resource' 
https = Net::HTTP.new uri.host, uri.port 
https.use_ssl = true 
https.post2 uri.path, data, 'Content-Type' => 'application/json' 
2

реальный пример из жизни, уведомит Airbrake API about new deployment через NetHttps

require 'uri' 
require 'net/https' 
require 'json' 

class MakeHttpsRequest 
    def call(url, hash_json) 
    uri = URI.parse(url) 
    req = Net::HTTP::Post.new(uri.to_s) 
    req.body = hash_json.to_json 
    req['Content-Type'] = 'application/json' 
    # ... set more request headers 

    response = https(uri).request(req) 

    response.body 
    end 

    private 

    def https(uri) 
    Net::HTTP.new(uri.host, uri.port).tap do |http| 
     http.use_ssl = true 
     http.verify_mode = OpenSSL::SSL::VERIFY_NONE 
    end 
    end 
end 

project_id = 'yyyyyy' 
project_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
url = "https://airbrake.io/api/v4/projects/#{project_id}/deploys?key=#{project_key}" 
body_hash = { 
    "environment":"production", 
    "username":"tomas", 
    "repository":"https://github.com/equivalent/scrapbook2", 
    "revision":"live-20160905_0001", 
    "version":"v2.0" 
} 

puts MakeHttpsRequest.new.call(url, body_hash) 

Примечание:

в случае, если вы делаете проверку подлинности с помощью авторизации заголовка установить заголовок req['Authorization'] = "Token xxxxxxxxxxxx" или http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html

Смежные вопросы