Skip to content

Instantly share code, notes, and snippets.

@stevenschobert
Last active February 2, 2017 19:17
Show Gist options
  • Select an option

  • Save stevenschobert/b26a08b704e164dcc67f to your computer and use it in GitHub Desktop.

Select an option

Save stevenschobert/b26a08b704e164dcc67f to your computer and use it in GitHub Desktop.
Standalone Net::HTTP wrapper class for interfacing with JSON APIs. I typically use this when I have many classes that need to talk to different APIs in a project. Otherwise if I'm building a single API client gem, I sometimes use this instead: https://gist.github.com/stevenschobert/8df1dc08a96ba0ecc274
class ApiClient
attr_accessor :base_url
attr_accessor :default_headers
attr_accessor :default_params
attr_accessor :basic_auth
attr_reader :body
def initialize(base_url:, headers: {}, params: {})
@base_url = base_url
@default_headers = headers || { "Accept" => "application/json" }
@default_params = params || {}
end
def accept_header=(value)
default_headers["Accept"] = value
end
def basic_auth=(value)
if Hash === value
@basic_auth = [ value[:username], value[:password] ]
else
@basic_auth = value
end
end
def json_response
if @body
JSON.parse(@body)
end
end
def get(path, params = {}, headers = {})
request(path, :get, params, headers)
json_response
end
def post(path, params = {}, headers = {})
request(path, :post, params, headers)
json_response
end
def request(path, method = :get, params = {}, headers = {})
path = "/#{ path }".gsub(/\/\//, "/")
url = "#{ base_url }#{ path }"
payload = nil
headers = default_headers.merge(headers)
params = default_params.merge(params)
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
if uri.port == 443
http.use_ssl = true
# optionally uncomment if you want to disable SSL verification
#http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = nil
case method
when :get
uri.query = URI.encode_www_form(params)
request = Net::HTTP::Get.new(uri)
when :post
request = Net::HTTP::Post.new(uri)
request.set_form_data(params.stringify_keys)
when :delete
request = Net::HTTP::Delete.new(uri)
request.set_form_data(params.stringify_keys)
when :patch
request = Net::HTTP::Patch.new(uri)
request.set_form_data(params.stringify_keys)
end
if request
headers.each do |key, value|
request[key] = value
end
if Array === basic_auth
request.basic_auth(*basic_auth)
end
response = http.request(request)
@body = parse_body(response, response.body)
response
end
end
protected
# Thanks
# https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb#L600
def parse_body(http_response, body)
content_encoding = http_response["content-encoding"]
if (!body) || body.empty?
body
elsif content_encoding == "gzip"
Zlib::GzipReader.new(StringIO.new(body)).read
elsif content_encoding == "deflate"
begin
Zlib::Inflate.new.inflate body
rescue Zlib::DataError
Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate body
end
else
body
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment