Skip to content

Instantly share code, notes, and snippets.

@zacheryph
Last active September 5, 2024 21:20
Show Gist options
  • Save zacheryph/11bd3c5ba5d5cdc3f6091e4794d1d723 to your computer and use it in GitHub Desktop.
Save zacheryph/11bd3c5ba5d5cdc3f6091e4794d1d723 to your computer and use it in GitHub Desktop.
api_wrapper.rb
# just for this example to work
class BigCommerce
def woot(...)
puts "woot"
end
class System
def time(*args, **kwargs)
puts "time: #{args} #{kwargs}"
end
end
class Product
def all(*args, **kwargs)
puts "all: #{kwargs}"
end
end
end
# the meat
class Client
attr_reader :site, :connection, :target
DEFAULT_TARGET = BigCommerce
def initialize(site, connection: nil)
@site = site
@connection = connection || "CONNECTION:#{site}"
@target = self.class::DEFAULT_TARGET.new
end
def self.expose(name, target = nil, &block)
target ||= name
if target.is_a?(Class)
klass = const_set(name.capitalize, Class.new(Client, &block))
klass.const_set(:DEFAULT_TARGET, target)
define_method(name) { klass.new(site, connection:) }
else
define_method(name) { |*args, **kwargs| @target.send(name, *args, **kwargs, connection:) }
end
end
expose :woot
expose :product, BigCommerce::Product do
expose :all
end
expose :system, BigCommerce::System do
expose :time
end
end
# the action
Client.new("my_site").woot
#=> woot
Client.new("my_site").product.all("arg", kw: "named arg")
#=> all: {:kw=>"named arg", :connection=>"CONNECTION:my_site"}
Client.new("my_site").system.time("arg", kw: "named arg")
#=> time: ["arg"] {:kw=>"named arg", :connection=>"CONNECTION:my_site"}
# the best part is you can instantiate single services if you really want to
Client::Product.new("my_site").all
#=> all: {:connection=>"CONNECTION:123"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment