Class: Billrb::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/billrb/client.rb

Overview

Thin HTTP layer over the BILL v3 API: session auth, retries, JSON, and error mapping. Knows nothing about individual resources.

A client may be shared across threads: sign-in is guarded by a mutex, so concurrent requests trigger at most one login and an expired session is refreshed only once even when many requests race on it.

Constant Summary collapse

BASE_PATH =
"/connect/v3"
IDEMPOTENT_METHODS =

HTTP methods with no side effects, so they are safe to retry on a 5xx or network error. 429 (rate limited) is retried for every method since the request was rejected before processing.

%i[get head options put delete].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = nil, **options) ⇒ Client

Accepts an explicit Configuration, inline options (Client.new(dev_key: “…”, …)), or falls back to Billrb.configuration.



24
25
26
27
28
29
30
31
32
33
# File 'lib/billrb/client.rb', line 24

def initialize(config = nil, **options)
  @config = if config
      config
    elsif options.any?
      Configuration.new(**options)
    else
      Billrb.configuration
    end
  @login_mutex = Mutex.new
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



20
21
22
# File 'lib/billrb/client.rb', line 20

def config
  @config
end

Instance Method Details

#delete(path) ⇒ Object



51
52
53
# File 'lib/billrb/client.rb', line 51

def delete(path)
  request(:delete, path)
end

#get(path, params = {}) ⇒ Object



35
36
37
# File 'lib/billrb/client.rb', line 35

def get(path, params = {})
  request(:get, path, params: params)
end

#inspectObject



71
72
73
74
# File 'lib/billrb/client.rb', line 71

def inspect
  "#<#{self.class.name} environment=#{config.environment.inspect} " \
  "authenticated=#{!@session_id.nil?}>"
end

#login!Object

Forces a fresh sign-in. Normally unnecessary — requests sign in lazily.



56
57
58
59
# File 'lib/billrb/client.rb', line 56

def login!
  @login_mutex.synchronize { do_login! }
  true
end

#logout!Object



61
62
63
64
65
66
67
68
69
# File 'lib/billrb/client.rb', line 61

def logout!
  @login_mutex.synchronize do
    return false unless @session_id

    parse!(perform(:post, "/logout"))
    @session_id = nil
  end
  true
end

#patch(path, body = nil) ⇒ Object



47
48
49
# File 'lib/billrb/client.rb', line 47

def patch(path, body = nil)
  request(:patch, path, body: body)
end

#post(path, body = nil) ⇒ Object



39
40
41
# File 'lib/billrb/client.rb', line 39

def post(path, body = nil)
  request(:post, path, body: body)
end

#put(path, body = nil) ⇒ Object



43
44
45
# File 'lib/billrb/client.rb', line 43

def put(path, body = nil)
  request(:put, path, body: body)
end