class SendGrid::Client

A simple REST client.

Attributes

host[R]
http[R]
request[R]
request_headers[R]
url_path[R]

Public Class Methods

new(host: nil, request_headers: nil, version: nil, url_path: nil, http_options: {}, proxy_options: {}) click to toggle source
  • Args :

    • host -> Base URL for the api. (e.g. api.sendgrid.com)

    • request_headers -> A hash of the headers you want applied on

      all calls
      
    • version -> The version number of the API.

      Subclass add_version for custom behavior.
      Or just pass the version as part of the URL
      (e.g. client._("/v3"))
    • url_path -> A list of the url path segments

    • proxy_options -> A hash of proxy settings.

      (e.g. { host: '127.0.0.1', port: 8080 })
# File lib/ruby_http_client.rb, line 99
def initialize(host: nil, request_headers: nil, version: nil, url_path: nil, http_options: {}, proxy_options: {}) # rubocop:disable Metrics/ParameterLists
  @host = host
  @request_headers = request_headers || {}
  @version = version
  @url_path = url_path || []
  @methods = %w[delete get patch post put]
  @query_params = nil
  @request_body = nil
  @http_options = http_options
  @proxy_options = proxy_options
end

Public Instance Methods

_(name = nil) click to toggle source

Add variable values to the url. (e.g. /your/api/{variable_value}/call) Another example: if you have a ruby reserved word, such as true, in your url, you must use this method.

  • Args :

    • name -> Name of the url segment

  • Returns :

# File lib/ruby_http_client.rb, line 274
def _(name = nil)
  url_path = name ? @url_path + [name] : @url_path
  Client.new(host: @host, request_headers: @request_headers,
             version: @version, url_path: url_path,
             http_options: @http_options)
end
add_http_options(http) click to toggle source

Add others http options to http object

  • Args :

    • http -> HTTP::NET object

  • Returns :

    • HTTP::NET object

# File lib/ruby_http_client.rb, line 257
def add_http_options(http)
  @http_options.each do |attribute, value|
    http.send("#{attribute}=", value)
  end
  http
end
add_ssl(http) click to toggle source

Allow for https calls

  • Args :

    • http -> HTTP::NET object

  • Returns :

    • HTTP::NET object

# File lib/ruby_http_client.rb, line 242
def add_ssl(http)
  if host.start_with?('https')
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  end
  http
end
add_version(url = nil) click to toggle source

Add the API version, subclass this function to customize

  • Args :

    • url -> An empty url string

  • Returns :

    • The url string with the version pre-pended

# File lib/ruby_http_client.rb, line 141
def add_version(url = nil)
  path = @version ? "/#{@version}" : ''
  url.concat(path)
end
build_args(args) click to toggle source

Set the query params, request headers and request body

# File lib/ruby_http_client.rb, line 164
def build_args(args)
  args.each do |arg|
    arg.each do |key, value|
      case key.to_s
      when 'query_params'
        @query_params = value
      when 'request_headers'
        update_headers(value)
      when 'request_body'
        @request_body = value
      end
    end
  end
end
build_http(host, port) click to toggle source

Build HTTP request object

  • Returns :

    • Request object

# File lib/ruby_http_client.rb, line 227
def build_http(host, port)
  params = [host, port]
  params += @proxy_options.values_at(:host, :port, :user, :pass) unless @proxy_options.empty?
  http = add_ssl(Net::HTTP.new(*params))
  http = add_http_options(http) unless @http_options.empty?
  http
end
build_query_params(url, query_params) click to toggle source

Add query parameters to the url

  • Args :

    • url -> path to endpoint

    • query_params -> hash of query parameters

  • Returns :

    • The url string with the query parameters appended

# File lib/ruby_http_client.rb, line 154
def build_query_params(url, query_params)
  params = URI.encode_www_form(query_params)
  url.concat("?#{params}")
end
build_request(name, args) click to toggle source

Build the API request for HTTP::NET

# File lib/ruby_http_client.rb, line 200
def build_request(name, args)
  build_args(args) if args
  # build the request & http object
  build_http_request(name)
  # set the content type & request body
  update_content_type(name)
  make_request(@http, @request)
end
build_request_headers(request) click to toggle source

Build the final request headers

  • Args :

    • request -> HTTP::NET request object

  • Returns :

    • HTTP::NET request object

# File lib/ruby_http_client.rb, line 127
def build_request_headers(request)
  @request_headers.each do |key, value|
    request[key] = value
  end
  request
end
build_url(query_params: nil) click to toggle source

Build the final url

  • Args :

    • query_params -> A hash of query parameters

  • Returns :

    • The final url string

# File lib/ruby_http_client.rb, line 186
def build_url(query_params: nil)
  url = [add_version(''), *@url_path].join('/')
  url = build_query_params(url, query_params) if query_params
  URI.parse("#{@host}#{url}")
end
make_request(http, request) click to toggle source

Make the API call and return the response. This is separated into it’s own function, so we can mock it easily for testing.

  • Args :

    • http -> NET:HTTP request object

    • request -> NET::HTTP request object

  • Returns :

# File lib/ruby_http_client.rb, line 218
def make_request(http, request)
  response = http.request(request)
  Response.new(response)
end
method_missing(name, *args, &_block) click to toggle source

Dynamically add segments to the url, then call a method. (e.g. client.name.name.get())

  • Args :

    • The args are automatically passed in

  • Returns :

rubocop:disable Style/MethodMissingSuper rubocop:disable Style/MissingRespondToMissing

# File lib/ruby_http_client.rb, line 291
def method_missing(name, *args, &_block)
  # Capture the version
  if name.to_s == 'version'
    @version = args[0]
    return _
  end
  # We have reached the end of the method chain, make the API call
  return build_request(name, args) if @methods.include?(name.to_s)

  # Add a segment to the URL
  _(name)
end
update_headers(request_headers) click to toggle source

Update the headers for the request

  • Args :

    • request_headers -> Hash of request header key/values

# File lib/ruby_http_client.rb, line 116
def update_headers(request_headers)
  @request_headers.merge!(request_headers)
end

Private Instance Methods

build_http_request(http_method) click to toggle source
# File lib/ruby_http_client.rb, line 306
def build_http_request(http_method)
  uri = build_url(query_params: @query_params)
  net_http = Kernel.const_get('Net::HTTP::' + http_method.to_s.capitalize)

  @http = build_http(uri.host, uri.port)
  @request = build_request_headers(net_http.new(uri.request_uri))
end
content_type_json?() click to toggle source
# File lib/ruby_http_client.rb, line 330
def content_type_json?
  !@request_headers.key?('Content-Type') ||
    @request_headers['Content-Type'] == 'application/json'
end
update_content_type(http_method) click to toggle source
# File lib/ruby_http_client.rb, line 314
def update_content_type(http_method)
  if @request_body && content_type_json?
    # If body is a hash or array, encode it; else leave it alone
    @request.body = if [Hash, Array].include?(@request_body.class)
                      @request_body.to_json
                    else
                      @request_body
                    end
    @request['Content-Type'] = 'application/json'
  elsif !@request_body && http_method.to_s == 'post'
    @request['Content-Type'] = ''
  else
    @request.body = @request_body
  end
end