class BookingSync::API::Client
Constants
- MEDIA_TYPE
Attributes
Public Class Methods
Initialize new Client
@param token [String] OAuth token @param options [Hash] @option options [String] base_url
: Base URL to BookingSync
site @option options [Logger] logger: Logger where headers and body of every
request and response will be logged.
@option options [Module] instrumenter: A module that responds to
instrument, usually ActiveSupport::Notifications.
@return [BookingSync::API::Client] New BookingSync
API
client
# File lib/bookingsync/api/client.rb, line 130 def initialize(token, options = {}) @token = token @logger = options[:logger] || default_logger @instrumenter = options[:instrumenter] || NoopInstrumenter @base_url = options[:base_url] @serializer = Serializer.new @conn = build_connection @conn.headers[:accept] = MEDIA_TYPE @conn.headers[:content_type] = MEDIA_TYPE @conn.headers[:user_agent] = user_agent @conn.url_prefix = api_endpoint yield @conn if block_given? end
Public Instance Methods
Make a HTTP request to given path and returns Response
object.
@param method [Symbol] HTTP verb to use. @param path [String] The path, relative to {#api_endpoint}. @param data [Hash] Data to be send in the request’s body
it can include query: key with requests params for GET requests
@param options [Hash] A customizable set of request options. @return [BookingSync::API::Response] A Response
object.
# File lib/bookingsync/api/client.rb, line 262 def call(method, path, data = nil, options = nil) instrument("call.bookingsync_api", method: method, path: path) do if [:get, :head].include?(method) options = data data = {} end options ||= {} options[:headers] ||= {} options[:headers]["Authorization"] = "Bearer #{token}" if options.has_key?(:query) if options[:query].has_key?(:ids) ids = Array(options[:query].delete(:ids)).join(",") path = "#{path}/#{ids}" end options[:query].keys.each do |key| if options[:query][key].is_a?(Array) options[:query][key] = options[:query][key].join(",") end end end url = expand_url(path, options[:uri]) res = @conn.send(method, url) do |req| if data req.body = data.is_a?(String) ? data : encode_body(data) end if params = options[:query] req.params.update params end req.headers.update options[:headers] end handle_response(res) end end
Decode a String response body to a Resource
.
@param str [String] The String body from the response. @return [Object] Object resource
# File lib/bookingsync/api/client.rb, line 208 def decode_body(str) @serializer.decode(str) end
Make a HTTP DELETE request
@param path [String] The path, relative to {#api_endpoint} @param options [Hash] Body params for the request @return [Array<BookingSync::API::Resource>]
# File lib/bookingsync/api/client.rb, line 185 def delete(path, options = {}) request :delete, path, options end
Make a HTTP GET request
@param path [String] The path, relative to {#api_endpoint} @param options [Hash] Query params for the request @return [Array<BookingSync::API::Resource>] Array of resources.
# File lib/bookingsync/api/client.rb, line 149 def get(path, options = {}) request :get, path, query: options end
Make a HTTP GET or POST request to a path with pagination support.
@param options [Hash] @option options [Integer] per_page: Number of resources per page @option options [Integer] page: Number of page to return @option options [Boolean] auto_paginate: If true, all resources will
be returned. It makes multiple requestes underneath and joins the results.
@yieldreturn [Array<BookingSync::API::Resource>] Batch of resources @return [Array<BookingSync::API::Resource>] Batch of resources
# File lib/bookingsync/api/client.rb, line 237 def paginate(path, options = {}, &block) instrument("paginate.bookingsync_api", path: path) do request_settings = { auto_paginate: options.delete(:auto_paginate), request_method: options.delete(:request_method) || :get } if block_given? data = fetch_with_block(path, options, request_settings, &block) else data = fetch_with_paginate(path, options, request_settings) end data end end
Make a HTTP PATCH request
@param path [String] The path, relative to {#api_endpoint} @param options [Hash] Body params for the request @return [Array<BookingSync::API::Resource>]
# File lib/bookingsync/api/client.rb, line 176 def patch(path, options = {}) request :patch, path, options end
Make a HTTP POST request
@param path [String] The path, relative to {#api_endpoint} @param options [Hash] Body params for the request @return [Array<BookingSync::API::Resource>]
# File lib/bookingsync/api/client.rb, line 158 def post(path, options = {}) request :post, path, options end
Make a HTTP PUT request
@param path [String] The path, relative to {#api_endpoint} @param options [Hash] Body params for the request @return [Array<BookingSync::API::Resource>]
# File lib/bookingsync/api/client.rb, line 167 def put(path, options = {}) request :put, path, options end
Make a HTTP request to a path and returns an Array of Resources
@param method [Symbol] HTTP verb to use. @param path [String] The path, relative to {#api_endpoint}. @param data [Hash] Data to be send in the request’s body
it can include query: key with requests params for GET requests
@param options [Hash] A customizable set of request options. @return [Array<BookingSync::API::Resource>] Array of resources.
# File lib/bookingsync/api/client.rb, line 220 def request(method, path, data = nil, options = nil) instrument("request.bookingsync_api", method: method, path: path) do response = call(method, path, data, options) response.respond_to?(:resources) ? response.resources : response end end
Yields client with temporarily modified headers.
@param extra_headers [Hash] Additional headers added to next request. @yieldreturn [BookingSync::API::Client] Client
with modified default headers. @return [Array<BookingSync::API::Resource>|BookingSync::API::Resource|String|Object] Client
response
# File lib/bookingsync/api/client.rb, line 303 def with_headers(extra_headers = {}, &block) original_headers = @conn.headers.dup @conn.headers.merge!(extra_headers) result = yield self @conn.headers = original_headers result end
Private Instance Methods
Return BookingSync
base URL. Default is www.bookingsync.com it can be altered via ENV variable BOOKINGSYNC_URL which is useful in specs when recording vcr cassettes. In also can be passed as :base_url option when initializing the Client
object
@return [String] Base URL to BookingSync
# File lib/bookingsync/api/client.rb, line 330 def base_url @base_url || ENV.fetch("BOOKINGSYNC_URL", "https://www.bookingsync.com") end
# File lib/bookingsync/api/client.rb, line 313 def build_connection Faraday.new(**faraday_options) do |f| f.use :logger, logger f.adapter :net_http_persistent end end
# File lib/bookingsync/api/client.rb, line 374 def debug? ENV["BOOKINGSYNC_API_DEBUG"] == "true" end
Return default logger. By default we don’t log anywhere. If we are in debug mode, we log everything to STDOUT.
@return [Logger] Logger where faraday middleware will log requests and
responses.
# File lib/bookingsync/api/client.rb, line 383 def default_logger Logger.new(debug? ? STDOUT : nil) end
Expand an URL template into a full URL
@param url [String|Addressable::Template] - An URL to be expanded @param options [Hash] - Variables which will be used to expand @return [String] - Expanded URL
# File lib/bookingsync/api/client.rb, line 349 def expand_url(url, options = nil) tpl = url.respond_to?(:expand) ? url : ::Addressable::Template.new(url.to_s) tpl.expand(options || {}).to_s end
# File lib/bookingsync/api/client.rb, line 320 def faraday_options { ssl: { verify: verify_ssl? } } end
# File lib/bookingsync/api/client.rb, line 409 def fetch_with_block(path, options, request_settings, response = nil, &block) response = initial_call(path, options, request_settings) unless response block.call(response.resources) if response.relations[:next] fetch_with_block(path, options, request_settings, next_page(response, request_settings), &block) end end
# File lib/bookingsync/api/client.rb, line 399 def fetch_with_paginate(path, options, request_settings, data = [], response = nil) response = initial_call(path, options, request_settings) unless response data.concat(response.resources) if response.relations[:next] && request_settings[:auto_paginate] fetch_with_paginate(path, options, request_settings, data, next_page(response, request_settings)) else data end end
Process faraday response.
@param faraday_response [Faraday::Response] - A response to process @raise [BookingSync::API::Unauthorized] - On unauthorized user @raise [BookingSync::API::UnprocessableEntity] - On validations error @return [BookingSync::API::Response|NilClass]
# File lib/bookingsync/api/client.rb, line 360 def handle_response(faraday_response) @last_response = response = Response.new(self, faraday_response) case response.status when 204; nil # destroy/cancel when 200..299; response when 401; raise Unauthorized.new(response) when 403; raise Forbidden.new(response) when 404; raise NotFound.new(response) when 422; raise UnprocessableEntity.new(response) when 429; raise RateLimitExceeded.new(response) else raise UnsupportedResponse.new(response) end end
# File lib/bookingsync/api/client.rb, line 417 def initial_call(path, options, request_settings) request_method = request_settings[:request_method] if request_method == :get response = call(request_method, path, query: options) else response = call(request_method, path, options) end @pagination_first_response = response end
# File lib/bookingsync/api/client.rb, line 427 def next_page(response, request_settings) response.relations[:next].call({}, { method: request_settings[:request_method] }) end
# File lib/bookingsync/api/client.rb, line 431 def reject_blank_values(array) array.reject { |value| value.nil? || value == "" } end
Return user agent with gem version, can be logged in API
.
# File lib/bookingsync/api/client.rb, line 388 def user_agent "BookingSync API gem v#{BookingSync::API::VERSION}" end
Return true if SSL cert should be verified By default is true, can be changed to false using env variable VERIFY_SSL
@return [Boolean] true if SSL needs to be verified false otherwise
# File lib/bookingsync/api/client.rb, line 340 def verify_ssl? ENV["BOOKINGSYNC_VERIFY_SSL"] != "false" end