Skip to content

Instantly share code, notes, and snippets.

@aviflombaum
Created July 9, 2024 22:47
Show Gist options
  • Save aviflombaum/150aa972705e543f8c677b98fd833307 to your computer and use it in GitHub Desktop.
Save aviflombaum/150aa972705e543f8c677b98fd833307 to your computer and use it in GitHub Desktop.
class BaseClient
class APINotFound < StandardError; end
attr_reader :auth_strategy
def initialize(auth_strategy: :headers, headers: {})
@auth_strategy = auth_strategy
@headers = headers
end
private
def get_response(endpoint)
response = HTTParty.get(endpoint_url(endpoint), request_options(endpoint))
handle_response(response, endpoint)
end
def delete_response(endpoint)
response = HTTParty.delete(endpoint_url(endpoint), request_options(endpoint))
handle_response(response, endpoint)
end
def post_response(endpoint, body)
response = HTTParty.post(endpoint_url(endpoint), request_options(endpoint, body))
handle_response(response, endpoint)
end
def put_response(endpoint, body)
response = HTTParty.put(endpoint_url(endpoint), request_options(endpoint, body))
handle_response(response, endpoint)
end
def get_response_with_params(endpoint, params)
query = URI.encode_www_form(params)
get_response("#{endpoint}?#{query}")
end
def request_options(endpoint, body = nil)
options = {
headers: headers
}
options[:body] = body.to_json if body
options.deep_merge(auth_options)
end
def auth_options
case auth_strategy
when :headers
{headers: api_auth}
when :basic_auth
{basic_auth: api_auth}
else
{}
end
end
def handle_response(response, endpoint)
case response.code
when 200, 201
response
when 404
raise BaseClient::APINotFound, "Endpoint #{endpoint} not found."
else
raise "Unable to connect to #{endpoint}: #{response.code} \n#{response.body}"
end
end
def endpoint_url(endpoint)
URI.join(base_url, endpoint).to_s
end
def base_url
raise NotImplementedError, "Subclasses must define `base_url`"
end
def api_auth
raise NotImplementedError, "Subclasses must define `api_auth`"
end
def headers
@headers.merge(default_headers)
end
def default_headers
{ "content-type" => "application/json", "accept" => "application/json" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment