Class: Medidata::API::REST

Inherits:
Object
  • Object
show all
Defined in:
lib/medidata/api/http.rb

Overview

A simple REST client.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host: nil, request_headers: nil, url_path: nil, http_options: {}, proxy_options: {}) ⇒ REST

  • 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
      (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 })
      


96
97
98
99
100
101
102
103
104
105
# File 'lib/medidata/api/http.rb', line 96

def initialize(host: nil, request_headers: nil, url_path: nil, http_options: {}, proxy_options: {}) # rubocop:disable Metrics/ParameterLists
  @host = host
  @request_headers = request_headers || {}
  @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

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 automatically passed in

  • Returns :

    • REST object or Response object

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



278
279
280
281
282
283
284
# File 'lib/medidata/api/http.rb', line 278

def method_missing(name, *args, &_block)
  # 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.



86
87
88
# File 'lib/medidata/api/http.rb', line 86

def host
  @host
end

#httpObject (readonly)

Returns the value of attribute http.



86
87
88
# File 'lib/medidata/api/http.rb', line 86

def http
  @http
end

#requestObject (readonly)

Returns the value of attribute request.



86
87
88
# File 'lib/medidata/api/http.rb', line 86

def request
  @request
end

#request_headersObject (readonly)

Returns the value of attribute request_headers.



86
87
88
# File 'lib/medidata/api/http.rb', line 86

def request_headers
  @request_headers
end

#url_pathObject (readonly)

Returns the value of attribute url_path.



86
87
88
# File 'lib/medidata/api/http.rb', line 86

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 :

    • REST object



258
259
260
261
262
263
264
265
266
# File 'lib/medidata/api/http.rb', line 258

def _(name = nil)
  url_path = name ? @url_path + [name] : @url_path
  REST.new(
    host: @host,
    request_headers: @request_headers,
    url_path: url_path,
    http_options: @http_options
  )
end

#add_http_options(http) ⇒ Object

Add others http options to http object

  • Args :

    • http -> HTTP::NET object

  • Returns :

    • HTTP::NET object



241
242
243
244
245
246
# File 'lib/medidata/api/http.rb', line 241

def add_http_options(http)
  @http_options.each do |attribute, value|
    http.send("#{attribute}=", value)
  end
  http
end

#add_ssl(http) ⇒ Object

Allow for https calls

  • Args :

    • http -> HTTP::NET object

  • Returns :

    • HTTP::NET object



226
227
228
229
230
231
232
# File 'lib/medidata/api/http.rb', line 226

def add_ssl(http)
  if host.start_with?('https')
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  end
  http
end

#build_args(args) ⇒ Object

Set the query params, request headers and request body

  • Args :

    • args -> array of args obtained from method_missing



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/medidata/api/http.rb', line 148

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) ⇒ Object

Build HTTP request object

  • Returns :

    • Request object



211
212
213
214
215
216
217
# File 'lib/medidata/api/http.rb', line 211

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) ⇒ 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



138
139
140
141
# File 'lib/medidata/api/http.rb', line 138

def build_query_params(url, query_params)
  params = URI.encode_www_form(query_params)
  url.concat("?#{params}")
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



184
185
186
187
188
189
190
191
# File 'lib/medidata/api/http.rb', line 184

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
  build_request_body(name)
  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



123
124
125
126
127
128
# File 'lib/medidata/api/http.rb', line 123

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



170
171
172
173
174
# File 'lib/medidata/api/http.rb', line 170

def build_url(query_params: nil)
  url = @url_path.join('/')
  url = build_query_params(url, query_params) if query_params
  URI.parse([@host, url].join('/'))
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



202
203
204
205
# File 'lib/medidata/api/http.rb', line 202

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



112
113
114
# File 'lib/medidata/api/http.rb', line 112

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