Skip to content

Instantly share code, notes, and snippets.

@danielabar
Forked from aviflombaum/base_client.rb
Created July 29, 2024 12:42

Revisions

  1. @aviflombaum aviflombaum created this gist Jul 9, 2024.
    88 changes: 88 additions & 0 deletions base_client.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,88 @@
    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