Skip to content

Instantly share code, notes, and snippets.

@hayduke19us
Created February 22, 2017 20:37
Show Gist options
  • Save hayduke19us/70a05084933968bdfbd2b2a922a99cea to your computer and use it in GitHub Desktop.
Save hayduke19us/70a05084933968bdfbd2b2a922a99cea to your computer and use it in GitHub Desktop.
require 'httparty'
module MultiRequest
extend ActiveSupport::Concern
def multi_request_queue
@multi_request_queue ||= RequestQueue.new
end
class RequestQueue
attr_reader :requests, :responses
attr_accessor :index
def initialize
@requests = []
@responses = []
end
def add(request, process: false)
requests.push({ request: request, process: process })
end
def start
requests.each_index do |index|
self.index = index
set_request_body
handle_request
end
self
end
def set_request_body
if previous_response && previous_response.valid?
current_request.body = previous_response.body
end
end
def handle_request
if current_request.valid?
handle_response current_request.call process: current_process
end
end
def handle_response(response)
responses.push response
end
def previous_response
responses[index - 1] if responses.any?
end
def current_request
requests[index][:request]
end
def current_process
requests[index][:process]
end
end
class Request
include ActiveModel::Validations
attr_accessor :method, :url, :headers, :body, :name
validates :method, :url, presence: true
validates :body, presence: true, if: lambda { method.to_sym == :post }
def initialize(args)
@headers = args.fetch :headers, _default_headers
@method = args.fetch :method
@url = args.fetch :url
@body = args[:body]
@name = args[:name]
end
def _default_headers
{ 'Accept' => 'application/json' }
end
def call(process: false)
Response.new process: process, accept: headers['Accept'], body: HTTParty.send(method, url, options).body
end
def options
{}.tap do |o|
o[:body] = body if body
o[:headers] = headers
end
end
end
class Response
include ActiveModel::Validations
attr_reader :accept, :body, :raw
attr_accessor :process
validates :body, :raw, presence: true
def initialize(args)
@accept = args.fetch :accept, 'application/json'
@raw = args.fetch :body
@process = args[:process]
@body = parse_body
end
def parse_body
parsed = case accept
when 'application/json' then JSON.parse raw
else
raw
end
process ? process.call(parsed) : parsed
rescue *_parsing_errors => e
errors.add :base, "Parsing error, #{e}"
raw
end
def _parsing_errors
[JSON::ParserError]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment