Ruby send JSON request

后端 未结 10 1205
后悔当初
后悔当初 2020-11-28 20:37

How do I send a JSON request in ruby? I have a JSON object but I dont think I can just do .send. Do I have to have javascript send the form?

Or can I us

相关标签:
10条回答
  • 2020-11-28 21:06

    It's 2020 - nobody should be using Net::HTTP any more and all answers seem to be saying so, use a more high level gem such as Faraday - Github


    That said, what I like to do is a wrapper around the HTTP api call,something that's called like

    rv = Transporter::FaradayHttp[url, options]

    because this allows me to fake HTTP calls without additional dependencies, ie:

      if InfoSig.env?(:test) && !(url.to_s =~ /localhost/)
        response_body = FakerForTests[url: url, options: options]
    
      else
        conn = Faraday::Connection.new url, connection_options
    

    Where the faker looks something like this

    I know there are HTTP mocking/stubbing frameworks, but at least when I researched last time they didn't allow me to validate requests efficiently and they were just for HTTP, not for example for raw TCP exchanges, this system allows me to have a unified framework for all API communication.


    Assuming you just want to quick&dirty convert a hash to json, send the json to a remote host to test an API and parse response to ruby this is probably fastest way without involving additional gems:

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

    Hopefully this goes without saying, but don't use this in production.

    0 讨论(0)
  • 2020-11-28 21:07

    real life example, notify Airbrake API about new deployment via 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)
    

    Notes:

    in case you doing authentication via Authorisation header set header req['Authorization'] = "Token xxxxxxxxxxxx" or http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html

    0 讨论(0)
  • 2020-11-28 21:08

    HTTParty makes this a bit easier I think (and works with nested json etc, which didn't seem to work in other examples I've seen.

    require 'httparty'
    HTTParty.post("http://localhost:3000/api/v1/users", body: {user: {email: 'user1@example.com', password: 'secret'}}).body
    
    0 讨论(0)
  • 2020-11-28 21:11
    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 讨论(0)
  • 2020-11-28 21:15

    This works on ruby 2.4 HTTPS Post with JSON object and the response body written out.

    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
    
    0 讨论(0)
  • 2020-11-28 21:19

    The net/http api can be tough to use.

    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 讨论(0)
提交回复
热议问题