Reputation: 32715
I have built a lightweight Ruby code to wrap an external API:
api = ExternalAPI.new
api.expensive_operation(object)
It works fine. However, since the API is expensive, I don't want to call it unless necessary. This is why I am creating a higher-level API that wraps the API call with local caching. I don't want the application to have to worry about the details about how the API is cached. (Caching could be accomplished by memory, disk, abaci, even pigeons -- it is not the application's concern.)
Here is what I am currently considering:
wrapper = ExternalAPIWrapper.new wrapper.expensive_operation(object)
I don't like about the name ExternalAPIWrapper
. It is generic, does not convey the purpose of the wrapper. In particular, it does not indicate that it is checks a local cache first and only hits the low-level API if necessary.
I'm looking for answers that improve upon this starting point. Here are some things I'm looking for:
Upvotes: 3
Views: 1088
Reputation: 32715
Rob, a friend of mine, found APICache:
APICache (aka api_cache)
APICache allows any API client library to be easily wrapped with a robust caching layer. It supports caching (obviously), serving stale data and limits on the number of API calls. It's also got a handy syntax if all you want to do is cache a bothersome url.
APICache supports multiple caching strategies, including:
Upvotes: 2
Reputation: 694
Too little detail to know exactly what you want but I thought of a bridge pattern straight away since you are essentially trying to decouple your abstraction and implementation when looking at varying your cache backend.
Upvotes: 0
Reputation: 25781
For #1 the name that comes to mind is CachedExternalAPI
:) Not sure what you mean by "a better style API", though.
As for #3/4: I don't know of a RubyGem that does this sort of caching thing, but I'd implement the cached API in a "metaprogramming" fashion, automatically generating the methods for the cached API calls, e.g.
class CachedExternalAPI
@cache = { }
class << self
[:foo, :bar, :baz].each do |m|
define_method m do
return (puts "Totally cached!"; @cache[m]) if not @cache[m].nil?
puts "Not cached :("
@cache[m] = 42
end
end
end
end
CachedExternalAPI.foo()
CachedExternalAPI.foo()
CachedExternalAPI.bar()
CachedExternalAPI.bar()
Which will yield
Not cached :(
Totally cached!
Not cached :(
Totally cached!
This of course assumes that the caching mechanism for all API calls is the same. But if your API is cachable that way, you can keep the cached API wrapper pretty DRY.
Upvotes: 3