Class: Tama::HTTP
- Inherits:
-
Object
- Object
- Tama::HTTP
- Defined in:
- lib/tama/http.rb
Constant Summary collapse
- RETRY_STATUSES =
[429, 500, 502, 503, 504].freeze
Instance Attribute Summary collapse
-
#base_uri ⇒ Object
readonly
Returns the value of attribute base_uri.
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
Class Method Summary collapse
Instance Method Summary collapse
- #check_status!(response) ⇒ Object
-
#initialize(base_url:, headers:, timeout:, retries:, connection: nil) ⇒ HTTP
constructor
A new instance of HTTP.
- #namespace! ⇒ Object
- #parse_body(response, model) ⇒ Object
- #parse_data(response, model, list: false) ⇒ Object
- #request(method, path, body: nil, query: nil, headers: {}, timeout: nil, &on_data) ⇒ Object
- #validate_namespace!(*allowed) ⇒ Object
Constructor Details
#initialize(base_url:, headers:, timeout:, retries:, connection: nil) ⇒ HTTP
Returns a new instance of HTTP.
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/tama/http.rb', line 15 def initialize(base_url:, headers:, timeout:, retries:, connection: nil) @base_uri = parse_base_url(base_url) @headers = Faraday::Utils::Headers.new(headers) @timeout = validate_timeout(timeout) @retries = validate_retries(retries) unless connection.nil? || connection.respond_to?(:run_request) raise Error::ConfigurationError, "connection must be a Faraday-compatible connection" end @connection = connection || build_connection end |
Instance Attribute Details
#base_uri ⇒ Object (readonly)
Returns the value of attribute base_uri.
13 14 15 |
# File 'lib/tama/http.rb', line 13 def base_uri @base_uri end |
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
13 14 15 |
# File 'lib/tama/http.rb', line 13 def connection @connection end |
Class Method Details
.segment(value, name) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/tama/http.rb', line 88 def self.segment(value, name) unless value.is_a?(String) && !value.empty? raise Error::ValidationError.new("#{name} must be a non-empty string", errors: {name => "must be a non-empty string"}) end CGI.escape(value).gsub("+", "%20") end |
Instance Method Details
#check_status!(response) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/tama/http.rb', line 74 def check_status!(response) status = response.status.to_i return response if status.between?(200, 299) body = parse_error_body(response.body) raise Error::NotFoundError.new(body:) if status == 404 if status == 422 errors = (body.is_a?(Hash) && body.key?("errors")) ? body["errors"] : body raise Error::ValidationError.new("API validation failed", errors:, status:) end raise Error::HTTPError.new(status:, body:) end |
#namespace! ⇒ Object
27 28 29 30 31 32 |
# File 'lib/tama/http.rb', line 27 def namespace! segments = base_uri.path.split("/").reject(&:empty?) raise Error::ConfigurationError, "Base URL must end with an operation namespace" if segments.empty? segments.last end |
#parse_body(response, model) ⇒ Object
69 70 71 72 |
# File 'lib/tama/http.rb', line 69 def parse_body(response, model) check_status!(response) model.parse(parse_json(response.body)) end |
#parse_data(response, model, list: false) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/tama/http.rb', line 54 def parse_data(response, model, list: false) check_status!(response) document = parse_json(response.body) raise Error::ParseError, "Response JSON must be an object with a data key" unless document.is_a?(Hash) && document.key?("data") data = document["data"] if list raise Error::ParseError, "Response data must be an array" unless data.is_a?(Array) data.map { |item| model.parse(item) } else model.parse(data) end end |
#request(method, path, body: nil, query: nil, headers: {}, timeout: nil, &on_data) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/tama/http.rb', line 42 def request(method, path, body: nil, query: nil, headers: {}, timeout: nil, &on_data) connection.run_request(method, absolute_url(path), body, merged_headers(headers)) do |request| request..timeout = validate_timeout(timeout || @timeout) request..on_data = on_data if on_data query&.each_pair { |key, value| request.params[key] = value } end rescue Error raise rescue Faraday::Error => e raise Error::TransportError.new(e., cause: e) end |
#validate_namespace!(*allowed) ⇒ Object
34 35 36 37 38 39 40 |
# File 'lib/tama/http.rb', line 34 def validate_namespace!(*allowed) namespace = namespace! return if allowed.include?(namespace) raise Error::InvalidNamespaceError, "Invalid client namespace. Expected one of #{allowed.inspect}, got #{namespace.inspect}" end |