# frozen_string_literal: true module ErpIntegration module Fulfil class Client attr_reader :api_keys_pool, :base_url attr_writer :connection, :faraday_adapter, :rotate_statuses def initialize(api_keys_pool:, base_url:, logger: nil) @api_keys_pool = api_keys_pool @base_url = base_url.strip @logger = logger end # Sets the default adapter for the Faraday Connection. # @return [Symbol] The default Faraday adapter def faraday_adapter @faraday_adapter ||= Faraday.default_adapter end # Sets up the Faraday connection to talk to the Fulfil API. # @return [Faraday::Connection] The configured Faraday connection def connection @connection ||= Faraday.new(url: base_url) do |faraday| faraday.headers = default_headers faraday.request :json # Encode request bodies as JSON faraday.request :retry # Retry transient failures faraday.response :follow_redirects faraday.response :json # Decode response bodies as JSON # Custom error handling for the error response faraday.use ErpIntegration::Middleware::ErrorHandling # Custom middleware for rotating API keys faraday.use ErpIntegration::Middleware::ApiKeysRotation, api_keys_pool: api_keys_pool # Custom middleware for logging requests and responses faraday.use ErpIntegration::Middleware::Logger, @logger if @logger # Adapter definition should be last in order to make the json parsers be loaded correctly faraday.adapter faraday_adapter end end %i[delete get patch put post].each do |action_name| define_method(action_name) do |path, options = {}| if api_key.nil? || base_url.nil? raise ErpIntegration::Error, 'The Fulfil API key and/or base URL are missing.' end rate_limiter.within_limit do connection.public_send(action_name, "api/#{version}/#{path}", options).body end end end # Sets the default version for the Fulfil API endpoints. # @return [String] The Fulfil API version to be used def version @version ||= 'v2' end private def api_key api_keys_pool.current_key end def rate_limiter RateLimiter.find_by_api_key(api_key) end def default_headers { 'Accept': 'application/json', 'Content-Type': 'application/json' } end end end end