Class: SendGrid::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_http_client.rb

Overview

A simple REST client.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host: nil, request_headers: nil, version: nil, url_path: nil) ⇒ Client

  • 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



33
34
35
36
37
38
39
40
41
# File 'lib/ruby_http_client.rb', line 33

def initialize(host: nil, request_headers: nil, version: nil, url_path: nil)
  @host = host
  @request_headers = request_headers ? request_headers : {}
  @version = version
  @url_path = url_path ? url_path : []
  @methods = %w(delete get patch post put)
  @query_params = nil
  @request_body = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &_block) ⇒ Object

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

  • Args :

    • The args are autmoatically passed in

  • Returns :

    • Client object or Response object



214
215
216
217
218
219
220
221
222
223
224
# File 'lib/ruby_http_client.rb', line 214

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

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host.



22
23
24
# File 'lib/ruby_http_client.rb', line 22

def host
  @host
end

#request_headersObject (readonly)

Returns the value of attribute request_headers.



22
23
24
# File 'lib/ruby_http_client.rb', line 22

def request_headers
  @request_headers
end

#url_pathObject (readonly)

Returns the value of attribute url_path.



22
23
24
# File 'lib/ruby_http_client.rb', line 22

def url_path
  @url_path
end

Instance Method Details

#_(name = nil) ⇒ Object

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 :

    • Client object



199
200
201
202
203
204
# File 'lib/ruby_http_client.rb', line 199

def _(name = nil)
  url_path = name ? @url_path.push(name) : @url_path
  @url_path = []
  Client.new(host: @host, request_headers: @request_headers,
             version: @version, url_path: url_path)
end

#add_ssl(http) ⇒ Object

Allow for https calls

  • Args :

    • http -> HTTP::NET object

  • Returns :

    • HTTP::NET object



180
181
182
183
184
185
186
187
# File 'lib/ruby_http_client.rb', line 180

def add_ssl(http)
  protocol = host.split(':')[0]
  if protocol == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
  http
end

#add_version(url) ⇒ Object

Add the API version, subclass this function to customize

  • Args :

    • url -> An empty url string

  • Returns :

    • The url string with the version pre-pended



73
74
75
76
# File 'lib/ruby_http_client.rb', line 73

def add_version(url)
  url.concat("/#{@version}")
  url
end

#build_args(args) ⇒ Object

Set the query params, request headers and request body

  • Args :

    • args -> array of args obtained from method_missing



102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ruby_http_client.rb', line 102

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_query_params(url, query_params) ⇒ Object

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



86
87
88
89
90
91
92
93
94
95
# File 'lib/ruby_http_client.rb', line 86

def build_query_params(url, query_params)
  url.concat('?')
  count = 0
  query_params.each do |key, value|
    url.concat('&') if count > 0
    url.concat("#{key}=#{value}")
    count += 1
  end
  url
end

#build_request(name, args) ⇒ Object

Build the API request for HTTP::NET

  • Args :

    • name -> method name, received from method_missing

    • args -> args passed to the method

  • Returns :

    • A Response object from make_request



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ruby_http_client.rb', line 142

def build_request(name, args)
  build_args(args) if args
  uri = build_url(query_params: @query_params)
  http = Net::HTTP.new(uri.host, uri.port)
  http = add_ssl(http)
  net_http = Kernel.const_get('Net::HTTP::' + name.to_s.capitalize)
  request = net_http.new(uri.request_uri)
  request = build_request_headers(request)
  request.body = @request_body.to_json if @request_body
  if request.body
    request['Content-Type'] = 'application/json'
  elsif !request.body and (name = "post")
    request['Content-Type'] = ''
  end
  make_request(http, request)
end

#build_request_headers(request) ⇒ Object

Build the final request headers

  • Args :

    • request -> HTTP::NET request object

  • Returns :

    • HTTP::NET request object



59
60
61
62
63
64
# File 'lib/ruby_http_client.rb', line 59

def build_request_headers(request)
  @request_headers.each do |key, value|
    request[key] = value
  end
  request
end

#build_url(query_params: nil) ⇒ Object

Build the final url

  • Args :

    • query_params -> A hash of query parameters

  • Returns :

    • The final url string



124
125
126
127
128
129
130
131
132
# File 'lib/ruby_http_client.rb', line 124

def build_url(query_params: nil)
  url = ''
  url = add_version(url) if @version
  @url_path.each do |x|
    url.concat("/#{x}")
  end
  url = build_query_params(url, query_params) if query_params
  URI.parse("#{@host}#{url}")
end

#make_request(http, request) ⇒ Object

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 :

    • Response object



168
169
170
171
# File 'lib/ruby_http_client.rb', line 168

def make_request(http, request)
  response = http.request(request)
  Response.new(response)
end

#update_headers(request_headers) ⇒ Object

Update the headers for the request

  • Args :

    • request_headers -> Hash of request header key/values



48
49
50
# File 'lib/ruby_http_client.rb', line 48

def update_headers(request_headers)
  @request_headers = @request_headers.merge(request_headers)
end