class RequestBuilder

This class handles all Rosette API requests.

Attributes

alternate_url[R]

Alternate Rosette API URL

binding_version[RW]

Rosette API binding version

http_client[R]

Rosette API HTTP client

params[RW]

Parameters to build the body of the request from

user_agent[R]

User-Agent string

user_key[RW]

Rosette API key

Public Class Methods

new(user_key, alternate_url, http_client, binding_version, params = {}, url_parameters = nil) click to toggle source
# File request_builder.rb, line 24
def initialize(user_key, alternate_url, http_client, binding_version,
               params = {}, url_parameters = nil)
  @user_key = user_key
  @alternate_url = alternate_url
  @http_client = http_client
  @binding_version = binding_version
  @params = params
  @user_agent = "Ruby/#{binding_version}/#{RUBY_VERSION}"

  return unless url_parameters

  @alternate_url = "#{@alternate_url}?#{URI.encode_www_form(url_parameters)}"
end

Public Instance Methods

get_response(http, request) click to toggle source

Gets response from HTTP connection.

Attributes

  • http - HTTP connection.

  • request - Prepared Rosette API request.

Returns JSON response or raises RosetteAPIError if encountered.

# File request_builder.rb, line 203
def get_response(http, request)
  response = http.request request

  if response.code == '200'
    response_headers = {}
    response.header.each_header { |key, value| response_headers[key] = value }
    response_headers = { responseHeaders: response_headers }

    JSON.parse(response.body).merge(response_headers)
  else
    message = JSON.parse(response.body)['message']
    code = JSON.parse(response.body)['code']
    raise RosetteAPIError.new code, message
  end
end
prepare_multipart_request(params) click to toggle source

Prepares a multipart/form-data POST request for Rosette API.

Attributes

  • params - Parameters to build the body of the request.

Returns a HTTP connection and the built POST request.

# File request_builder.rb, line 93
def prepare_multipart_request(params)
  begin
    file = File.open params['filePath'], 'r'
    text = file.read
  rescue StandardError => e
    raise RosetteAPIError.new('readMultipartError', e)
  end

  boundary = SecureRandom.hex
  post_body = []
  params.delete 'filePath'
  request_file = params.to_json

  # Add the content data
  post_body << "--#{boundary}\r\n"
  post_body << 'Content-Disposition: form-data; name="content"; ' \
               "filename=\"#{File.basename(file)}\"\r\n"
  post_body << "Content-Type: text/plain\r\n\r\n"
  post_body << text

  # Add the request data
  post_body << "\r\n\r\n--#{boundary}\r\n"
  post_body << "Content-Disposition: form-data; name=\"request\"\r\n"
  post_body << "Content-Type: application/json\r\n\r\n"
  post_body << request_file
  post_body << "\r\n\r\n--#{boundary}--\r\n"

  # Create the HTTP objects
  begin
    uri = URI.parse @alternate_url
    request = Net::HTTP::Post.new uri.request_uri
  rescue StandardError
    # Not ideal.  Consider switching to a different library.
    # https://stackoverflow.com/a/11802674
    raise RosetteAPIError.new(
      'connectionError',
      'Failed to establish connection with Rosette API server.'
    )
  end

  # add any custom headers from the user
  unless params['customHeaders'].nil?
    keys_array = params['customHeaders'].keys
    keys_array.each do |k|
      if k.to_s =~ /^X-RosetteAPI-/
        request.add_field k, params['customHeaders'][k]
      else
        raise RosetteAPIError.new(
          'invalidHeader',
          'Custom header must begin with "X-RosetteAPI-"'
        )
      end
    end
    params.delete 'customHeaders'
  end

  request.add_field 'Content-Type',
                    "multipart/form-data; boundary=#{boundary}"
  request.add_field 'User-Agent', @user_agent
  request.add_field 'X-RosetteAPI-Key', @user_key
  request.add_field 'X-RosetteAPI-Binding', 'ruby'
  request.add_field 'X-RosetteAPI-Binding-Version', @binding_version
  request.body = post_body.join

  [@http_client, request]
end
prepare_plain_request(params) click to toggle source

Prepares a plain POST request for Rosette API.

Attributes

  • params - Parameters to build the body of the request.

Returns a HTTP connection and the built POST request.

# File request_builder.rb, line 45
def prepare_plain_request(params)
  begin
    uri = URI.parse @alternate_url
    request = Net::HTTP::Post.new uri.request_uri
  rescue StandardError
    # Not ideal.  Consider switching to a different library.
    # https://stackoverflow.com/a/11802674
    raise RosetteAPIError.new(
      'connectionError',
      'Failed to establish connection with Rosette server.'
    )
  end

  custom_headers = params['customHeaders']

  if custom_headers
    keys_array = custom_headers.keys
    keys_array.each do |key|
      if key.to_s =~ /^X-RosetteAPI-/
        request[key] = custom_headers[key]
      else
        raise RosetteAPIError.new(
          'invalidHeader',
          'Custom header must begin with "X-RosetteAPI-"'
        )
      end
    end
    params.delete 'customHeaders'
  end

  request['X-RosetteAPI-Key'] = @user_key
  request['Content-Type'] = 'application/json'
  request['Accept'] = 'application/json'
  request['User-Agent'] = @user_agent
  request['X-RosetteAPI-Binding'] = 'ruby'
  request['X-RosetteAPI-Binding-Version'] = @binding_version
  request.body = params.to_json

  [@http_client, request]
end
send_get_request() click to toggle source

Sends a GET request to Rosette API.

Returns JSON response or raises RosetteAPIError if encountered.

# File request_builder.rb, line 163
def send_get_request
  begin
    uri = URI.parse @alternate_url
    request = Net::HTTP::Get.new uri.request_uri
  rescue StandardError
    # Not ideal.  Consider switching to a different library.
    # https://stackoverflow.com/a/11802674
    raise RosetteAPIError.new(
      'connectionError',
      'Failed to establish connection with Rosette API server.'
    )
  end
  request['X-RosetteAPI-Key'] = @user_key
  request['User-Agent'] = @user_agent

  get_response @http_client, request
end
send_post_request() click to toggle source

Sends a POST request to Rosette API.

Returns JSON response or raises RosetteAPIError if encountered.

# File request_builder.rb, line 184
def send_post_request
  if params['filePath']
    http, request = prepare_multipart_request params
  else
    http, request = prepare_plain_request params
  end

  get_response http, request
end