lib/seam/request.rb in seam-2.0.0b5 vs lib/seam/request.rb in seam-2.0.0.prerelease.1

- old
+ new

@@ -1,106 +1,73 @@ # frozen_string_literal: true -require "faraday" -require "faraday/retry" -require_relative "lts_version" -require_relative "version" +require "http" module Seam - module Http - module Request - def self.create_faraday_client(endpoint, auth_headers, faraday_options = {}, faraday_retry_options = {}) - default_options = { - url: endpoint, - headers: auth_headers.merge(default_headers) - } + class Request + attr_reader :base_uri, :api_key, :debug - options = deep_merge(default_options, faraday_options) + class Error < StandardError + attr_reader :status, :response - default_faraday_retry_options = { - max: 2, - backoff_factor: 2 - } - - faraday_retry_options = default_faraday_retry_options.merge(faraday_retry_options) - - Faraday.new(options) do |builder| - builder.request :json - builder.response :json - builder.use ResponseMiddleware - builder.request :retry, faraday_retry_options - end + def initialize(message, status, response) + super(message) + @status = status + @response = response end + end - def self.default_headers - { - "User-Agent" => "seam-ruby/#{Seam::VERSION}", - "Content-Type" => "application/json", - :"seam-sdk-name" => "seamapi/ruby", - :"seam-sdk-version" => Seam::VERSION, - :"seam-lts-version" => Seam::LTS_VERSION - } - end + def initialize(api_key:, base_uri:, debug: false) + @api_key = api_key + @base_uri = base_uri + @debug = debug + end - class ResponseMiddleware < Faraday::Response::RaiseError - def on_complete(env) - return if env.success? + def perform(method, uri, config = {}) + Logger.info("Request: #{method} #{uri} #{config}") if debug - status_code = env.status - request_id = env.response_headers["seam-request-id"] + config[:body] = config[:body].to_json if config[:body] - raise Http::UnauthorizedError.new(request_id) if status_code == 401 + response = HTTP.request( + method, + build_url(uri), + {headers: headers}.merge(config) + ) - if seam_api_error_response?(env) - body = JSON.parse(env.body) - error = body["error"] - error_details = { - type: error["type"] || "unknown_error", - message: error["message"] || "Unknown error", - data: error["data"] - } + return response.parse if response.status.success? - if error["type"] == "invalid_input" - error_details["validation_errors"] = error["validation_errors"] - raise Http::InvalidInputError.new(error_details, status_code, request_id) - end + handle_error_response(response, method, uri) + end - raise Http::ApiError.new(error_details, status_code, request_id) - end + protected - super - end + def handle_error_response(response, method, uri) + msg = "Api Error #{response.status.code} #{method} #{uri}" + code = response.status.code - def seam_api_error_response?(env) - return false unless env.response_headers + if code >= 400 && code < 500 && (err = response.parse["error"]) + msg = "Api Error #{err["type"]}\nrequest_id: #{err["request_id"]}\n#{err["message"]}" + end - content_type = env.response_headers["Content-Type"] - return false unless content_type&.start_with?("application/json") + raise Error.new(msg, code, response) + end - begin - body = JSON.parse(env.body) - return false unless body.is_a?(Hash) && body["error"].is_a?(Hash) + def build_url(uri) + "#{base_uri}#{uri}" + end - error = body["error"] - error["type"].is_a?(String) && error["message"].is_a?(String) - rescue JSON::ParserError - false - end - end - end + def headers + { + "User-Agent" => user_agent, + "Content-Type" => "application/json", + "Authorization" => "Bearer #{api_key}", + :"seam-sdk-name" => "seamapi/ruby", + :"seam-sdk-version" => Seam::VERSION, + :"seam-lts-version" => Seam::LTS_VERSION + } + end - def self.deep_merge(hash1, hash2) - result = hash1.dup - hash2.each do |key, value| - result[key] = if value.is_a?(Hash) && result[key].is_a?(Hash) - deep_merge(result[key], value) - else - value - end - end - result - end - - private_class_method :deep_merge + def user_agent + "seam-ruby/#{Seam::VERSION}" end end end