Class: Setsuzoku::Service::WebService::ApiStrategies::RestStrategy

Inherits:
Setsuzoku::Service::WebService::ApiStrategy show all
Extended by:
T::Helpers, T::Sig
Defined in:
lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb

Overview

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

Instance Attribute Summary

Attributes included from ApiStrategy

#current_action, #service

Attributes included from HasConfigContext

#config_context

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Setsuzoku::Service::WebService::ApiStrategy

#api_headers, #parse_response

Methods included from ApiStrategy

#call_external_api, #final, #initialize, #parse_response

Methods included from HasConfigContext

#get_from_context

Class Method Details

.required_instance_methodsObject



21
22
23
# File 'lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb', line 21

def self.required_instance_methods
  []
end

Instance Method Details

#formulate_request(request_properties = {}, request_options = {}) ⇒ Object

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

Parameters:

  • request_properties (Hash) (defaults to: {})

    information pertaining to the body of the request

  • request_options (Hash) (defaults to: {})

    information pertainint to the headers of the request



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# 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 }) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# 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) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 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: {}) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# 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_classObject



17
18
19
# 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 = {}) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# 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