Rails
RSpec
vcr
rapa

Amazon Product Advertising APIをVCR化する

More than 1 year has passed since last update.

お願い

Troubleshooting Applications - Product Advertising APIを読むと10秒に1リクエスト、1日に8,640リクエストと書いてありますが、3リクエストくらい送ると You are submitting requests too quickly. Please retry your requests at a slower rate. となり、2-3時間待たないと復活せず困っています。開発段階で売り上げが0の状態での中、ガシガシAPIを叩いているせいかなと思っています。この辺、知っている人がいればコメントください :bow:

背景

個人でAmazon Product Advertising APIを利用している。APIリクエスト上限数が厳しく、動作確認が手間なのでmock化したい。webmockとvcrを利用してHTTPのmockを作成する | Act as Professional を参考に進めた。

やったこと

app/model/book.rb
class Book < ApplicationRecord
  def self.find_or_create_by_isbn(isbn13)
    book = self.find_or_initialize_by(isbn: isbn13)
    if book.new_record?
      librarian = Librarian.new
      # https://github.com/r7kamura/rapa/ を使って
      # Amazon Product Advertising APIをコールしてresponse値をセットする処理
      librarian.register!(book)
    end
    book
  end
end
spec/models/book_spec.rb
RSpec.describe Book, type: :model do
  describe "Add a new book" do
    context "with valid ISBN-13 code", :vcr do
      let(:book){ Book.find_or_create_by_isbn("9784822248970") }
      it "returns new record without any errors" do
        expect(book.isbn).to eq("9784822248970")
        expect(book.title).to eq("リーン・スタートアップ")
        expect(book.author).to eq("エリック・リース")
      end
    end
  end
end

ハマったことと

2回目以降、 An HTTP request has been made that VCR does not know how to handle となり困った。調べて見ると、Amazon Product Advertising APIは SignatureTimestamp は可変値なので、無視してあげないと同一リクエストとしてみてくれない様。

対応

match_requests_on を追記してあげれば良さそうだが、 vcr: { match_requests_on: [:method, uri_without_params] } do みたいな書き方をしているコードが多く、冗長になるが嫌だった。spec_helper で default_cassette_options として設定してしまうことにした。

spec_helper.rb
uri_without_params = VCR.request_matchers.uri_without_param(:Signature, :Timestamp)
VCR.configure do |config|
  config.cassette_library_dir = "spec/cassettes"
  config.configure_rspec_metadata!
  config.debug_logger = File.open("log/vcr.log", "w")
  config.default_cassette_options = { match_requests_on: [:method, uri_without_params] }
  config.hook_into :webmock
end

課題

今後、VCR化したいAPIが増えた時にどうするかは別途考える必要がある。