class Setsuzoku::Service::WebService::ApiStrategies::RestStrategy

Defines all necessary methods for handling interfacing with a REST API.

Public Class Methods

required_instance_methods() click to toggle source
# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 21
def self.required_instance_methods
  []
end

Public Instance Methods

formulate_request(request_properties = {}, request_options = {}) click to toggle source

Create the proper request body based on the request_properties and request_options passed

@param request_properties [Hash] information pertaining to the body of the request @param request_options [Hash] information pertainint to the headers of the request

@return full_request [Hash/String] returns the request body in the format required

# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 122
def formulate_request(request_properties = {}, request_options = {})
  request_format = request_properties.dig(:request_format).to_s
  params = request_properties[:req_params].merge(request_options.except(:headers))

  if request_properties[:request_method] == :get || request_properties[:req_params].empty?
    params
  else
    # if the header or request format include urlencoded return the body as a hash
    if request_format.include?('urlencoded')
      params
    else
      # return either xml or json
      if request_properties[:request_format] == :xml
        convert_hash_to_xml(params)
      else
        params.to_json
      end
    end
  end
end
get_request_properties(action_name:, for_stub: false, req_params: {}, action_details: { actions: self.plugin.api_actions, url: self.plugin.api_base_url }) click to toggle source
# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 95
def get_request_properties(action_name:, for_stub: false, req_params: {}, action_details: { actions: self.plugin.api_actions, url: self.plugin.api_base_url })
  action = action_details[:actions][action_name]
  url = action.has_key?(:request_url) ? action[:request_url] : action_details[:url]
  request_method, endpoint = action.first
  request_method = request_method.downcase.to_sym
  request_format = action[:request_type]
  response_format = action[:response_type]
  stub_data = action[:stub_data] if for_stub
  full_url = url + endpoint
  formatted_full_url, req_params = self.replace_dynamic_vars(full_url: full_url, req_params: req_params)
  {
      request_method: request_method,
      endpoint: endpoint,
      request_format: request_format,
      response_format: response_format,
      formatted_full_url: formatted_full_url,
      req_params: req_params,
      stub_data: stub_data,
  }
end
perform_external_call(request:, action_details:, **options) click to toggle source
# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 39
def perform_external_call(request:, action_details:, **options)
  request_properties = self.get_request_properties(action_name: request.action, action_details: action_details, req_params: request.body)
  request_options = self.request_options(request_properties[:request_format], action_details[:actions][request.action])
  authorization = request_options.delete(:authorization)
  full_request = self.formulate_request(request_properties, request_options)

  @faraday = Faraday.new(url: request_properties[:formatted_full_url], request: { params_encoder: Faraday::FlatParamsEncoder }) do |faraday|
    faraday.request(:multipart) if options[:attachment_urls].present?
    faraday.request(:url_encoded)
    #TODO: change these to faraday = self.auth_strategy.set_authorization!(request: faraday)
    unless request.without_headers
      if authorization
        if authorization.key?(:token)
          faraday.authorization(:Bearer, authorization[:token])
        elsif authorization.key?(:basic_auth)
          faraday.request(:basic_auth, authorization[:basic_auth][:username], authorization[:basic_auth][:password])
        end
      end
    end
    faraday.adapter Faraday.default_adapter
  end

  if options[:attachment_urls].present?
    resp = @faraday.post do |req|
      payload = {}
      attachments = options[:attachment_urls].map do |url|
        image = open(url, 'rb')
        Faraday::UploadIO.new(image, T.must(image).content_type, File.basename(url))
      end
      if request_properties[:request_format] == :json
        payload[:json] = Faraday::UploadIO.new(StringIO.new(full_request), 'application/json')
      else
        payload.merge!(full_request)
      end
      payload[options[:attachment_url_key]] = attachments
      req.body = payload
    end
  else
    if request.without_headers
      @faraday.headers = {}
    elsif request_options[:headers]
      @faraday.headers = (@faraday.headers || {}).merge(request_options[:headers])
    end
    resp = @faraday.send(request_properties[:request_method], request_properties[:formatted_full_url], full_request)
  end
  resp
end
replace_dynamic_vars(full_url:, req_params: {}) click to toggle source
# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 170
def replace_dynamic_vars(full_url:, req_params: {})
  # replace matching vars in the action with matching params.
  # scans the string for variables like {{number_sid}} and replaces it with the matching key in params
  # removes the params variable, as it's probably intended to be in the url only. If you encounter a need to have
  # it in the body and the url, then you should put it in params twice with different names.
  req_params = req_params.dup
  full_url = full_url.dup
  dynamic_vars = self.plugin.dynamic_url_params.merge(req_params).with_indifferent_access
  full_url.scan(/({{.*?}})/).flatten.each do |var|
    var_name = var.tr('{{ }}', '')
    next unless dynamic_vars[var_name]

    full_url.gsub!(var, dynamic_vars[var_name])
    req_params.delete(var_name)
    req_params.delete(var_name.to_sym)
  end
  [full_url, req_params]
end
request_class() click to toggle source
# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 17
def request_class
  RestAPIRequest
end
request_options(request_format = nil, action_details = {}) click to toggle source
# File lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb, line 143
def request_options(request_format = nil, action_details = {})
  request_options = {}
  (request_options = {})[:headers] = {}
  request_options[:headers]
    .merge!(self.auth_strategy.get_from_context(:auth_headers).except(:authorization))
    .merge!(self.get_from_context(:api_headers))
    .merge!(action_details[:request_options] || {})
  request_options[:authorization] = action_details[:authorization] || self.auth_strategy.get_from_context(:auth_headers)[:authorization]

  content_type = case request_format
                 when :json
                   'application/json'
                 when :xml
                   'application/xml'
                 when :text, :file
                   'text/plain'
                 when :pdf
                   'application/pdf'
                 when :'x-www-form-urlencoded;charset=UTF-8'
                   'application/x-www-form-urlencoded;charset=UTF-8'
                 else
                   'application/json'
                 end
  (request_options[:headers] ||= {})[:'Content-Type'] = content_type
  request_options
end