class Lutaml::Hal::Client
HAL Client for making HTTP requests to HAL APIs
def create_connection
def create_connection Faraday.new(url: @api_url) do |conn| conn.use Faraday::FollowRedirects::Middleware conn.request :json conn.response :json, content_type: /\bjson$/ conn.adapter Faraday.default_adapter end end
def debug_api_log(response, url)
def debug_api_log(response, url) if defined?(Rainbow) puts Rainbow("\n===== Lutaml::Hal DEBUG: HAL API REQUEST =====").blue else puts "\n===== Lutaml::Hal DEBUG: HAL API REQUEST =====" end puts "URL: #{url}" puts "Status: #{response.status}" # Format headers as JSON puts "\nHeaders:" headers_hash = response.headers.to_h puts JSON.pretty_generate(headers_hash) puts "\nResponse body:" if response.body.is_a?(Hash) || response.body.is_a?(Array) puts JSON.pretty_generate(response.body) else puts response.body.inspect end if defined?(Rainbow) puts Rainbow("===== END DEBUG OUTPUT =====\n").blue else puts "===== END DEBUG OUTPUT =====\n" end end
def get(url, params = {})
def get(url, params = {}) cache_key = "#{url}:#{params.to_json}" return @cache[cache_key] if @cache_enabled && @cache.key?(cache_key) @last_response = @connection.get(url, params) response = handle_response(@last_response, url) @cache[cache_key] = response if @cache_enabled response rescue Faraday::ConnectionFailed => e raise ConnectionError, "Connection failed: #{e.message}" rescue Faraday::TimeoutError => e raise TimeoutError, "Request timed out: #{e.message}" rescue Faraday::ParsingError => e raise ParsingError, "Response parsing error: #{e.message}" rescue Faraday::Adapter::Test::Stubs::NotFound => e raise LinkResolutionError, "Resource not found: #{e.message}" end
def get_by_url(url, params = {})
def get_by_url(url, params = {}) # Strip API endpoint if it's included path = strip_api_url(url) get(path, params) end
def handle_response(response, url)
def handle_response(response, url) debug_api_log(response, url) if @debug case response.status when 200..299 response.body when 400 raise BadRequestError, response_message(response) when 401 raise UnauthorizedError, response_message(response) when 404 raise NotFoundError, response_message(response) when 500..599 raise ServerError, response_message(response) else raise Error, response_message(response) end end
def initialize(options = {})
def initialize(options = {}) @api_url = options[:api_url] || raise(ArgumentError, 'api_url is required') @connection = options[:connection] || create_connection @params_default = options[:params_default] || {} @debug = options[:debug] || !ENV['DEBUG_API'].nil? @cache = options[:cache] || {} @cache_enabled = options[:cache_enabled] || false @api_url = strip_api_url(@api_url) end
def response_message(response)
def response_message(response) message = "Status: #{response.status}" message += ", Error: #{response.body['error']}" if response.body.is_a?(Hash) && response.body['error'] message end
def strip_api_url(url)
def strip_api_url(url) url.sub(%r{/\Z}, '') end