保存来自 API 调用的响应以用于测试,这样我就不必不断重复对 API 的请求

Save a response from API call to use in a test so I don't have to continuously repeat requests to API

API 请求花费的时间太长,并且在我的 Rails 集成测试和我的应用程序中花费了我的钱。

我想保存 API 回复,然后使用该数据进行测试。有什么好的方法可以做到这一点吗?

此外,如何才能在 production/development 中减少 api 次调用?我可以使用哪种缓存?

我会将 http://redis.io/ 与 jbuilder 等软件结合使用。因此,作为示例,您的视图如下所示:

json.cache! ["cache", "plans_index"] do
  json.array! @plans do |plan|
    json.partial! plan
  end
end

对于此控制器:

  def index
    @plans = Plan.all
  end

如果你有一个展示页面,你可以像这样缓存它:

json.cache! ["cache", "plan_#{params["id"]}"] do
  json.extract! @plan, :short_description, :long_description, 
end

如果我没理解错的话,你的 rails 应用正在使用外部 api,比如 google/fb/twitter api,这种东西

缓存视图不起作用,因为它只缓存模板,所以它不会浪费时间再次渲染视图,它通过散列数据验证缓存是热的,代码仍然会这样做点击 api 以验证哈希值是否仍然匹配

对你来说,最好的方法是使用一个 class 来执行所有 api 调用,并将它们缓存在 rails 缓存中并给该缓存一个超时时间,因为你不希望你的缓存太陈旧,但同时你会为了一些钱牺牲一些准确性(比如每 5、15、30 分钟只调用一次,无论你选择哪个)

这是我的想法的示例,但您应该修改它以满足您的需要

module ApiWrapper
  class << self
    def some_method(some_key) # if keys are needed, like an id or something
      Rails.cache.fetch("some_method/#{some_key}", expires_in: 5.minutes) do
        # assuming ApiLibrary is the external library handler
        ApiLibrary.call_external_library(some_key)
      end
    end
  end
end

然后在您的代码中,调用该包装器,如果缓存中的存储值已过期,它只会联系外部 api。

电话会是这样的

# assuming 5 is the id or value you want to fetch from the api
ApiWrapper.some_method(5)

您可以从 rails guide for caching

阅读更多关于缓存方法的信息


更新:

我只是想到了另一种方法,对于您的测试(如 rspec 测试),您可以对 api 调用进行存根,这样您将保存整个 api 调用,除非你正在测试 api it self,使用我上面写的相同 api 库,我们可以存根 ApiLibrary it self

allow(ApiLibrary).to receive(:some_method).and_return({ data: 'some fake data' })

PS:散列键 data 是 return 的一部分,它是整个散列而不仅仅是字符串。

有一个很棒的 gem 这个叫做 VCR。它允许您发出单个请求并缓存响应,因此每次您 运行 测试时都将使用这个保存的响应。