class Medidata::API::REST
A simple REST
client.
Attributes
Public Class Methods
-
Args :
-
host
-> Base URL for the api. (e.g. api.sendgrid.com) -
request_headers
-> A hash of the headers you want applied onall 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 })
-
# 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
Public Instance Methods
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
-
# 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 others http options to http object
-
Args :
-
http
-> HTTP::NET object
-
-
Returns :
-
HTTP::NET object
-
# 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
Allow for https calls
-
Args :
-
http
-> HTTP::NET object
-
-
Returns :
-
HTTP::NET object
-
# 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
Set the query params, request headers and request body
-
Args :
-
args
-> array of args obtained frommethod_missing
-
# 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 request object
-
Returns :
-
Request object
-
# 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
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/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 the API
request for HTTP::NET
-
Args :
-
name
-> method name, received frommethod_missing
-
args
-> args passed to the method
-
-
Returns :
-
A
Response
object frommake_request
-
# 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 the final request headers
-
Args :
-
request
-> HTTP::NET request object
-
-
Returns :
-
HTTP::NET request object
-
# 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 the final url
-
Args :
-
query_params
-> A hash of query parameters
-
-
Returns :
-
The final url string
-
# 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 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
-
# File lib/medidata/api/http.rb, line 202 def make_request(http, request) response = http.request(request) Response.new(response) end
Dynamically add segments to the url, then call a method. (e.g. client.name.name.get())
rubocop:disable Style/MethodMissingSuper rubocop:disable Style/MissingRespondToMissing
# 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
Update the headers for the request
-
Args :
-
request_headers
-> Hash of request header key/values
-
# File lib/medidata/api/http.rb, line 112 def update_headers(request_headers) @request_headers.merge!(request_headers) end
Private Instance Methods
# File lib/medidata/api/http.rb, line 288 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
# File lib/medidata/api/http.rb, line 296 def build_request_body(http_method) if @request_body && is_json_request? && [Hash, Array].include?(@request_body.class) @request.body = @request_body.to_json @request['Content-Type'] = 'application/json' elsif !@request_body && http_method.to_s != 'get' @request['Content-Type'] = '' else @request['Content-Type'] = @request_headers[:'Content-Type'] @request.body = @request_body end end
# File lib/medidata/api/http.rb, line 308 def is_json_request? !@request_headers.key?(:'Content-Type') || @request_headers[:'Content-Type'] == 'application/json' end