रूबी JSON अनुरोध भेजें


86

मैं रूबी में JSON अनुरोध कैसे भेजूं? मेरे पास एक JSON ऑब्जेक्ट है लेकिन मुझे नहीं लगता कि मैं बस कर सकता हूं .send। क्या मुझे जावास्क्रिप्ट को फॉर्म भेजना होगा?

या मैं रूबी में नेट / http वर्ग का उपयोग कर सकता हूं?

हेडर के साथ - सामग्री प्रकार = json और बॉडी json ऑब्जेक्ट?

जवाबों:


76
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

8
मुझे होस्टनाम और पोर्ट को संभालने के लिए URI का उपयोग करने का आपका सुझाव पसंद है, जो अन्यथा काफी थकाऊ है। लेकिन आप पोस्ट.न्यू (...) में uri.path सेट करना भूल गए:req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/json'})
ArnauOrriols

1
सबसे सरल, सबसे साफ प्रतिक्रिया। यह भी खूब रही।
जोएलक

http.request(req).read_bodyप्रतिक्रिया शरीर को पढ़ने के लिए। महान!
आईजी

1
मुझे पूरा यकीन है कि यह 2.4.1 में बदल गया है, लेकिन मेरे भगवान। वह वाक्य-विन्यास स्थूल है। यह जानता है कि यह Post.new () से यूआरआई है इसलिए आपको शुरू में (), मूल्यों को फिर से विभाजित करना होगा। कुल। कोई आश्चर्य नहीं कि रूबी में इतने सारे अन्य पैकेज हैं जो http से निपटते हैं।
रामबेटिनो

50
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

किस अपवाद को निर्दिष्ट किया जाना चाहिए
Mio

7
Https अनुरोधों के लिए बस जोड़ें: http.use_ssl = true।
कौशल M2

17

HTTParty इसे थोड़ा आसान बनाता है जो मुझे लगता है (और नेस्टेड json आदि के साथ काम करता है, जो मुझे दिखाई देने वाले अन्य उदाहरणों में काम नहीं करता है)।

require 'httparty'
HTTParty.post("http://localhost:3000/api/v1/users", body: {user: {email: 'user1@example.com', password: 'secret'}}).body

6

वास्तविक जीवन उदाहरण, NetHttps के माध्यम से नई तैनाती के बारे में Airbrake API को सूचित करें

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 के माध्यम से प्रमाणीकरण कर रहे हैं


... लेकिन ईमानदारी से यह अच्छा है और सभी वास्तविक रूप से रहते हैं, लेकिन मैं सिर्फ HTTParty stackoverflow.com/a/14491995/473040 :) का उपयोग करूंगा ... खासकर यदि आप https से निपटने के साथ काम कर रहे हैं
बराबर 8

uri की आवश्यकता बेकार है क्योंकि यह पहले से ही नेट / http
noraj

@ समतुल्य: "वास्तविक जीवन में मैं सिर्फ HTTParty का उपयोग करूंगा" - वह यह है कि जब तक आप एक दुबला रत्न नहीं बना रहे हैं, या अन्यथा कोई अन्य निर्भरता नहीं चाहते हैं। :)
सर्जियो तुलन्त्सेव

@SergioTulentsev सहमत ... जब तक आप मणि / लिबास (या रूबी आधारित माइक्रो सर्विस) का निर्माण नहीं कर रहे हैं जहां आप अनावश्यक निर्भरता का परिचय नहीं देना चाहते हैं;)
बराबर

4

एक साधारण json POST उन लोगों के लिए उदाहरण का अनुरोध करता है जिन्हें टॉम की लिंकिंग की तुलना में यह और भी सरल चाहिए।

require 'net/http'

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

19
ऐसा लगता है कि इसे काम करना चाहिए, लेकिन पोस्ट_फॉर्म पैरामीटर को कुंजी = मूल्य और कुंजी = मूल्य सिंटैक्स में अनुवाद करता है। यदि आप JSON स्ट्रिंग के लिए अनुरोध निकाय के साथ एक POST करना चाहते हैं, तो मुझे लगता है कि आपको एक अलग समाधान की आवश्यकता है।
बेन गोटोव

यह गहरी नेस्टेड जोंस के साथ काम नहीं करता है। पहले स्तर से परे कुछ भी एक स्ट्रिंग बन जाता है।
नीयनी

डोंट बस की तरह दिखते हैं। यह काम करता हैं। यह सरल है। लेकिन उदाहरण के लिए साधारण चीजों की तरह मैंने इसे ठीक काम किया है
क्रिस्टोफर

4
यह मूलभूत रूप से JSON अनुरोध नहीं है। यह एक urlencoded निकाय है। कोई JSON नहीं है हेडर भी उतना ही कहता है। यह किसी भी उदाहरण के साथ काम नहीं करता है, कभी भी।
रिल्लू

4
यह उत्तर गलत है। यह एक POST है जो माइम / मल्टीपार्ट में है, एक url है जो इसमें "json" कहता है।
जॉन हौगलैंड ११

4

यह 2020 है - किसी को Net::HTTPभी अधिक का उपयोग नहीं करना चाहिए और सभी उत्तर ऐसा कहते प्रतीत होते हैं, अधिक उच्च स्तर के मणि का उपयोग करें जैसे कि फैराडे - गालूब


उस ने कहा, मुझे जो करना पसंद है वह है HTTP एपीआई कॉल के आसपास एक आवरण, कुछ ऐसा जिसे कहा जाता है

rv = Transporter::FaradayHttp[url, options]

क्योंकि यह मुझे अतिरिक्त निर्भरता के बिना HTTP कॉल नकली करने की अनुमति देता है, अर्थात:

  if InfoSig.env?(:test) && !(url.to_s =~ /localhost/)
    response_body = FakerForTests[url: url, options: options]

  else
    conn = Faraday::Connection.new url, connection_options

जहां फकर कुछ इस तरह नजर आए

मुझे पता है कि HTTP मॉकिंग / स्टबिंग फ्रेमवर्क हैं, लेकिन कम से कम जब मैंने पिछली बार शोध किया तो उन्होंने मुझे कुशलता से अनुरोधों को मान्य करने की अनुमति नहीं दी और वे सिर्फ HTTP के लिए थे, उदाहरण के लिए कच्चे टीसीपी एक्सचेंजों के लिए नहीं, यह प्रणाली मुझे अनुमति देती है सभी एपीआई संचार के लिए एकीकृत रूपरेखा।


यह मानते हुए कि आप बस त्वरित और गंदे को हैश में बदलना चाहते हैं, एक दूरस्थ मेजबान को एक एपीआई का परीक्षण करने के लिए जोंस को भेजें और माणिक की प्रतिक्रिया को पार्स करें, यह अतिरिक्त रत्नों को शामिल किए बिना शायद सबसे तेज़ तरीका है:

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

उम्मीद है कि यह कहे बिना चला जाता है, लेकिन उत्पादन में इसका उपयोग न करें।


2
लोल, सभी नफरत क्यों करते हैं? :) पोस्ट स्पष्ट रूप से उत्पादन या किसी अन्य गंभीर उद्देश्य के लिए नहीं बताता है, लेकिन एक JSON
एपि

आप NTLM प्रमाणीकरण का उपयोग करके ऐसा नहीं कर सकते। इसलिए नेट :: HTTP अभी भी केवल एक ही पुस्तकालय है जो इसका समर्थन करता है।
रौनक

1
'किसी को भी इस्तेमाल नहीं करना चाहिए' से असहमत Net::HTTPहैं
JellicleCat

@Bbozonobody should be using Net::HTTP any more
Patricio Sard

3

यह JSON ऑब्जेक्ट और बाहर लिखी गई प्रतिक्रिया बॉडी के साथ रूबी 2.4 HTTPS पोस्ट पर काम करता है।

require 'net/http' #net/https does not have to be required anymore
require 'json'
require 'uri'

uri = URI('https://your.secure-url.com')
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
  request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
  request.body = {parameter: 'value'}.to_json
  response = http.request request # Net::HTTPResponse object
  puts "response #{response.body}"
end

2

मुझे यह हल्का वजन http अनुरोध ग्राहक thisunirest 'कहा जाता है।

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

1

नेट / http एप का उपयोग करने के लिए कठिन हो सकता है।

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

यह कोड काम नहीं करता है। आपको नेट :: HTTP को # स्टार्ट के साथ इनिशियलाइज़ करना होगा:Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |client|
टायलर

गहरे लाल रंग का 2.3.7p456 (2018/03/28 संशोधन 63024) [universal.x86_64-darwin18] के साथ काम करता है
मोरियार्टी

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'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.