def do_json_request(method, url, params = nil, additional_headers = {}, &create_response)
      begin
        if params
          additional_headers.merge!(self.class.json_body_headers)
        end
        response = do_request(method, url, (params.to_json if params), additional_headers)
      rescue RestClient::Exception => e
        # Attempt to parse the body as JSON if possible
        error_details = begin
                          e.http_body ? JSON.parse(e.http_body) : nil
                        rescue JSON::ParserError
                          nil
                        end
        raise build_specific_http_error(e, url, error_details, params)
      end

      # If no custom response is given, just instantiate Response
      create_response ||= Proc.new { |r| Response.new(r) }
      create_response.call(response)
    end
def do_json_request(method, url, params = nil, additional_headers = {}, &create_response)
      begin
        if params
          additional_headers.merge!(self.class.json_body_headers)
        end
        response = do_request(method, url, (params.to_json if params), additional_headers)
      rescue RestClient::Exception => e
        # Attempt to parse the body as JSON if possible
        error_details = begin
                          e.http_body ? JSON.parse(e.http_body) : nil
                        rescue JSON::ParserError
                          nil
                        end
        raise build_specific_http_error(e, url, error_details, params)
      end

      # If no custom response is given, just instantiate Response
      create_response ||= Proc.new { |r| Response.new(r) }
      create_response.call(response)
    end
method: the symbolic name of the method to use, e.g. :get, :post
 url:    the request URL
 params: the data to send (JSON-serialised) in the request body
 additional_headers: headers to set on the request (in addition to the default ones)
 create_response: optional block to instantiate a custom response object
                  from the Net::HTTPResponse