class Postmen::Connection

Connection class is used to perform any HTTP connections, it also does error handling.

Constants

FAILOVER_DOMAIN

Failover domain used during DNS issues with main domain

MAIN_DOMAIN

Main domain used during normal usage.

MAX_REQUESTS

Maximum number of retries

Public Class Methods

endpoint(subdomain, failover = false) click to toggle source

Returns the endpoint used in SDK, based on the region(subdomain) and a failover switch

@param subdomain [String] The region/subdomain used. @param failover [Boolean]

# File lib/postmen/connection.rb, line 73
def self.endpoint(subdomain, failover = false)
  URI::HTTPS.build(scheme: 'https',
                   host: hostname(subdomain, failover),
                   path: '/v3').to_s
end
hostname(subdomain, failover) click to toggle source

Returns the hostname based on the region(subdomain) and a failover switch

@param subdomain [String] The region/subdomain used. @param failover [Boolean]

# File lib/postmen/connection.rb, line 83
def self.hostname(subdomain, failover)
  base = failover ? FAILOVER_DOMAIN : MAIN_DOMAIN
  [subdomain, base].join('.')
end
new() click to toggle source
# File lib/postmen/connection.rb, line 14
def initialize
  @requests = 0
end

Public Instance Methods

delete(path) click to toggle source

Performs a HTTP DELETE request

@param path [String] @example

.delete('/shipper-accounts/11111')
# File lib/postmen/connection.rb, line 62
def delete(path)
  HTTP
    .headers(headers)
    .delete(get_full_url(path))
end
get(path, options = {}) click to toggle source

Performs a HTTP GET request.

@param path [String] @param options [Hash] @example

.get('/labels')
.get('/labels', { params: { limit: 5 } })
# File lib/postmen/connection.rb, line 25
def get(path, options = {})
  with_error_handling do
    Response.new(raw_get(path, options)).tap(&:parse_response!)
  end
end
post(path, options = {}) click to toggle source

Performs a HTTP POST request.

@param path [String] @param options [Hash] @example

.post('/labels')
.post('/labels', { json: { my: { sample: :data } } })
# File lib/postmen/connection.rb, line 38
def post(path, options = {})
  with_error_handling do
    Response.new(raw_post(path, options))
  end
end
put(path, options = {}) click to toggle source

Performs a HTTP PUT request.

@param path [String] @param options [Hash] @example

.put('/shipper-accounts/123/info')
..put('/shipper-accounts/123/info', { json: { my: { sample: :data } } })
# File lib/postmen/connection.rb, line 51
def put(path, options = {})
  with_error_handling do
    Response.new(raw_put(path, options)).tap(&:parse_response!)
  end
end

Private Instance Methods

get_full_url(path) click to toggle source
# File lib/postmen/connection.rb, line 154
def get_full_url(path)
  [Postmen.endpoint, path].join
end
headers() click to toggle source
# File lib/postmen/connection.rb, line 158
def headers
  {
    "content-type": 'application/json',
    "postmen-api-key": Postmen.config.api_key
  }
end
raw_get(path, options) click to toggle source
# File lib/postmen/connection.rb, line 136
def raw_get(path, options)
  HTTP
    .headers(headers)
    .get(get_full_url(path), options)
end
raw_post(path, options) click to toggle source
# File lib/postmen/connection.rb, line 142
def raw_post(path, options)
  HTTP
    .headers(headers)
    .post(get_full_url(path), options)
end
raw_put(path, options) click to toggle source
# File lib/postmen/connection.rb, line 148
def raw_put(path, options)
  HTTP
    .headers(headers)
    .put(get_full_url(path), options)
end
with_error_handling() { || ... } click to toggle source

rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize rubocop:disable Metrics/CyclomaticComplexity

# File lib/postmen/connection.rb, line 93
def with_error_handling
  raise ArgumentError unless block_given?

  begin
    yield
  # Rescue from any  connection issues
  rescue HTTP::ConnectionError
    # Raise error if we already tried to use failover domain
    raise if Postmen.failover?
    # Switch to failover domain & retry the request
    Postmen.failover!
    retry
  # Handle Rate limits.
  # Rate limits are being reset every 60 seconds - we're retrying
  # given request after that.
  # @see https://docs.postmen.com/ratelimit.html Documentation
  rescue RateLimitExceeded
    @requests += 1
    raise if @requests > MAX_REQUESTS
    sleep(60)
    retry
  # If the resource was not found, simply re-raise the exception
  rescue ResourceNotFound
    raise
  # Handle request errors.
  # Our current error handling policy depends on the error type.
  # If the API returns information, that the request is retriable,
  # We're waiting 5 seconds, and trying again with exact same request.
  # To prevent having infinite loops, we're trying maximum 5 times.
  # In case that we were unable to make successfull request with that 5 tries,
  # MaximumNumberOfRetriesReachedError is being raised.
  #
  # @raise RequestError if the request is not retriable
  # @raise MaximumNumberOfRetriesReachedError if the API returned error after 5 retries
  rescue RequestError => error
    raise unless error.retriable?
    raise MaximumNumberOfRetriesReachedError, self if @requests > MAX_REQUESTS
    @requests += 1
    sleep(5)
    retry
  end
end