From d5ea45b92959ff7909619a659623d99f6e7379f9 Mon Sep 17 00:00:00 2001 From: citin Date: Thu, 8 Aug 2024 14:44:13 +0200 Subject: [PATCH] merge-pagination --- .rubocop.yml | 1 - lib/beyond_api/all_pages_handler.rb | 52 ++++++++++++ lib/beyond_api/concerns/connection.rb | 81 +++++++++++++++++++ lib/beyond_api/concerns/pagination.rb | 15 ++++ lib/beyond_api/connection.rb | 78 ------------------ .../services/authentication/token.rb | 2 +- lib/beyond_api/services/base_service.rb | 37 +-------- .../services/product_management/image.rb | 2 +- .../services/product_management/product.rb | 4 +- .../services/product_management/variation.rb | 2 +- .../product_management/variation_image.rb | 2 +- .../services/product_view/category.rb | 3 +- 12 files changed, 156 insertions(+), 123 deletions(-) create mode 100644 lib/beyond_api/all_pages_handler.rb create mode 100644 lib/beyond_api/concerns/connection.rb create mode 100644 lib/beyond_api/concerns/pagination.rb delete mode 100644 lib/beyond_api/connection.rb diff --git a/.rubocop.yml b/.rubocop.yml index f60d3dc..1af1fa2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,4 @@ require: - - rubocop-ordered_methods - rubocop-rspec AllCops: diff --git a/lib/beyond_api/all_pages_handler.rb b/lib/beyond_api/all_pages_handler.rb new file mode 100644 index 0000000..99ba7ed --- /dev/null +++ b/lib/beyond_api/all_pages_handler.rb @@ -0,0 +1,52 @@ +module BeyondApi + class AllPagesHandler + include Concerns::Connection + + def initialize(session, url, params = {}) + @session = session + @url = url + @params = params + + first_page_data = fetch_page(0) + @response = first_page_data + @resource_key = first_page_data[:embedded].keys.first + @total_pages = first_page_data.dig(:page, :total_pages) + @total_elements = first_page_data.dig(:page, :total_elements) + end + + def call + (1..remaining_pages).each do |page| + process_page(page) + end + + update_response_page_info + + @response + end + + private + + def remaining_pages + @total_pages - 1 + end + + def fetch_page(page) + # Fixed page size + get(@url, @params.merge(page:, size: BeyondApi.configuration.all_pagination_size)) + end + + def process_page(page) + page_data = fetch_page(page) + + @response[:embedded][@resource_key].concat( + page_data[:embedded][@resource_key] + ) + end + + def update_response_page_info + @response[:page][:size] = @total_elements + @response[:page][:total_pages] = 1 + @response[:page][:number] = 0 + end + end +end diff --git a/lib/beyond_api/concerns/connection.rb b/lib/beyond_api/concerns/connection.rb new file mode 100644 index 0000000..0217a80 --- /dev/null +++ b/lib/beyond_api/concerns/connection.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module BeyondApi + module Concerns + module Connection + LOGGER = BeyondApi.logger + LOGGER.level = Kernel.const_get("::Logger::#{BeyondApi.configuration.log_level.to_s.upcase}") + + def get(path, params = {}) + parsed_response agent.get(path, params) + end + + def post(path, body = {}, params = {}) + response = agent.post(path, body) do |request| + request.params = params + request.body = parsed_body(body) + end + parsed_response(response) + end + + def delete(path, params = {}) + parsed_response agent.delete(path, params) + end + + private + + def parsed_response(response) + Response.new(response).handle + end + + def parsed_body(body) + Utils.camelize_keys(body) + end + + def agent + @agent ||= Faraday.new(url: @session.api_url, ssl: { verify: true }) do |faraday| + # Timeouts + faraday.options.timeout = BeyondApi.configuration.timeout.to_i + faraday.options.open_timeout = BeyondApi.configuration.open_timeout.to_i + # Authorization + case @authorization + when :basic + faraday.request :authorization, :basic, BeyondApi.configuration.client_id, + BeyondApi.configuration.client_secret + when :bearer + faraday.request :authorization, "Bearer", @session.access_token + end + # Headers + faraday.headers["Accept"] = "application/json" # Set default accept header + faraday.headers["Content-Type"] = "application/json" # Set default content type + # Request options + faraday.request :json # Encode request bodies as JSON + faraday.request :retry, BeyondApi.configuration.retry_options + # Response options + faraday.response :json, content_type: "application/json" + faraday.response :logger, *logger_config { |logger| apply_filters(logger) } + end + end + + def apply_filters(logger) + logger.filter(/(code=)([a-zA-Z0-9]+)/, '\1[FILTERED]') + logger.filter(/(refresh_token=)([a-zA-Z0-9.\-\_]+)/, '\1[FILTERED]') + end + + # def multipart + # create_connection do |faraday| + # faraday.adapter Faraday.default_adapter + # faraday.request :multipart, flat_encode: true + # end + # end + + def logger_config + [ + LOGGER, + { bodies: BeyondApi.configuration.log_bodies, + headers: BeyondApi.configuration.log_headers } + ] + end + end + end +end diff --git a/lib/beyond_api/concerns/pagination.rb b/lib/beyond_api/concerns/pagination.rb new file mode 100644 index 0000000..21403cd --- /dev/null +++ b/lib/beyond_api/concerns/pagination.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module BeyondApi + module Concerns + module Pagination + def fetch_all_pages(url, params = {}) + if params[:paginated] == false + AllPagesHandler.new(@session, url, params).call + else + get(url, params) + end + end + end + end +end diff --git a/lib/beyond_api/connection.rb b/lib/beyond_api/connection.rb deleted file mode 100644 index 2d8c73c..0000000 --- a/lib/beyond_api/connection.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -module BeyondApi - module Connection - LOGGER = BeyondApi.logger - LOGGER.level = Kernel.const_get("::Logger::#{BeyondApi.configuration.log_level.to_s.upcase}") - - def get(path, params = {}) - parsed_response agent.get(path, params) - end - - def post(path, body = {}, params = {}) - response = agent.post(path, body) do |request| - request.params = params - request.body = parsed_body(body) - end - parsed_response(response) - end - - def delete(path, params = {}) - parsed_response agent.delete(path, params) - end - - private - - def parsed_response(response) - Response.new(response).handle - end - - def parsed_body(body) - Utils.camelize_keys(body) - end - - def agent - @agent ||= Faraday.new(url: @session.api_url, ssl: { verify: true }) do |faraday| - # Timeouts - faraday.options.timeout = BeyondApi.configuration.timeout.to_i - faraday.options.open_timeout = BeyondApi.configuration.open_timeout.to_i - # Authorization - case @authorization - when :basic - faraday.request :authorization, :basic, BeyondApi.configuration.client_id, BeyondApi.configuration.client_secret - when :bearer - faraday.request :authorization, "Bearer", @session.access_token - end - # Headers - faraday.headers["Accept"] = "application/json" # Set default accept header - faraday.headers["Content-Type"] = "application/json" # Set default content type - # Request options - faraday.request :json # Encode request bodies as JSON - faraday.request :retry, BeyondApi.configuration.retry_options - # Response options - faraday.response :json, content_type: "application/json" - faraday.response :logger, *logger_config { |logger| apply_filters(logger) } - end - end - - def apply_filters(logger) - logger.filter(/(code=)([a-zA-Z0-9]+)/, '\1[FILTERED]') - logger.filter(/(refresh_token=)([a-zA-Z0-9.\-\_]+)/, '\1[FILTERED]') - end - - # def multipart - # create_connection do |faraday| - # faraday.adapter Faraday.default_adapter - # faraday.request :multipart, flat_encode: true - # end - # end - - def logger_config - [ - LOGGER, - { bodies: BeyondApi.configuration.log_bodies, - headers: BeyondApi.configuration.log_headers } - ] - end - end -end diff --git a/lib/beyond_api/services/authentication/token.rb b/lib/beyond_api/services/authentication/token.rb index f5487ff..9f52e32 100644 --- a/lib/beyond_api/services/authentication/token.rb +++ b/lib/beyond_api/services/authentication/token.rb @@ -1,7 +1,7 @@ module BeyondApi module Authentication class Token - include Connection # @session, @authorization + include Concerns::Connection # @session, @authorization def initialize(session = nil) @session = session diff --git a/lib/beyond_api/services/base_service.rb b/lib/beyond_api/services/base_service.rb index af16fc5..f6ad19d 100644 --- a/lib/beyond_api/services/base_service.rb +++ b/lib/beyond_api/services/base_service.rb @@ -1,6 +1,7 @@ module BeyondApi class BaseService - include Connection # @session, @authorization + include Concerns::Connection # @session, @authorization + include Concerns::Pagination ServiceSession = Struct.new(:api_url, :access_token, :refresh_token) @@ -9,16 +10,6 @@ def initialize(**params) @authorization = :bearer end - def fetch_all_pages(url, resource, params = {}) - if params[:paginated] == false - result = fetch_pages(url, resource, params) - adjust_response(result) - result - else - fetch_page(url, 0, params) - end - end - private def initialize_session(session) @@ -28,29 +19,5 @@ def initialize_session(session) session[:refresh_token] ) end - - def adjust_response(result) - result[:page][:size] = result[:page][:total_elements] - result[:page][:total_pages] = 1 - result[:page][:number] = 0 - end - - # FIXME: find another way - def fetch_page(url, page, params = {}) - params.merge!(page:, size: BeyondApi.configuration.all_pagination_size) - BeyondApi::Request.new(@session).get(url, params) - end - - def fetch_pages(url, resource, params) - result = fetch_page(url, 0, params) - - (1..result[:page][:total_pages] - 1).each do |page| - result[:embedded][resource].concat( - fetch_page(url, page, params)[:embedded][resource] - ) - end - - result - end end end diff --git a/lib/beyond_api/services/product_management/image.rb b/lib/beyond_api/services/product_management/image.rb index 50cb0da..72b0cb4 100644 --- a/lib/beyond_api/services/product_management/image.rb +++ b/lib/beyond_api/services/product_management/image.rb @@ -1,7 +1,7 @@ module BeyondApi module ProductManagement class Image < BaseService - def all(id) + def all(id, params = {}) get("products/#{id}/images") end end diff --git a/lib/beyond_api/services/product_management/product.rb b/lib/beyond_api/services/product_management/product.rb index 56f9c8d..1ad5c35 100644 --- a/lib/beyond_api/services/product_management/product.rb +++ b/lib/beyond_api/services/product_management/product.rb @@ -2,9 +2,7 @@ module BeyondApi module ProductManagement class Product < BaseService def all(params = {}) - # Request.new(@session).get("products", params) - # fetch_all_pages("/products", :products, params) - get("products", params) + fetch_all_pages("/products", params) end def find(id) diff --git a/lib/beyond_api/services/product_management/variation.rb b/lib/beyond_api/services/product_management/variation.rb index 12d00a1..41ba8b2 100644 --- a/lib/beyond_api/services/product_management/variation.rb +++ b/lib/beyond_api/services/product_management/variation.rb @@ -1,7 +1,7 @@ module BeyondApi module ProductManagement class Variation < BaseService - def all(id) + def all(id, params = {}) get("products/#{id}/variations") end end diff --git a/lib/beyond_api/services/product_management/variation_image.rb b/lib/beyond_api/services/product_management/variation_image.rb index 22194a9..4a3367b 100644 --- a/lib/beyond_api/services/product_management/variation_image.rb +++ b/lib/beyond_api/services/product_management/variation_image.rb @@ -1,7 +1,7 @@ module BeyondApi module ProductManagement class VariationImage < BaseService - def all(product_id, variation_id) + def all(product_id, variation_id, params = {}) get("products/#{product_id}/variations/#{variation_id}/images") end end diff --git a/lib/beyond_api/services/product_view/category.rb b/lib/beyond_api/services/product_view/category.rb index 005042c..5cb1efc 100644 --- a/lib/beyond_api/services/product_view/category.rb +++ b/lib/beyond_api/services/product_view/category.rb @@ -2,8 +2,7 @@ module BeyondApi module ProductView class Category < BaseService def all(params = {}) - # fetch_all_pages("product-view/categories", :categories, params) - get("product-view/categories", params) + fetch_all_pages("product-view/categories", params) end def find(id)