Amazon Product Advertising API 用のクライアントライブラリをつくっている

Amazon Product Advertising API とは

Product Advertising API は、Amazon の商品情報や関連コンテンツをプログラムを通してアクセスできるサービスを提供することで、Web 開発者の皆様が、ご自分の Web サイトでAmazon の商品を紹介することによる紹介料の獲得を可能とします。

https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html

要は、Amazon のアソシエイトを使って商品を宣伝する目的で、Amazon の商品情報を API 経由で操作することができるサービスが提供されている。この記事は、この APIRuby から利用するためのライブラリをつくっているという話。

GitHub

ソースコードGitHub で管理されている。ライブラリの API 寄りの説明が README に書かれている。

https://github.com/r7kamura/rapa

rubygems.org

rubygems.org にも登録されているので、Gem として取得できる。執筆時点でのバージョンは 0.2.1。

https://rubygems.org/gems/rapa

既存のライブラリ

Amazon Product Advertising APIRuby から利用するための既存のライブラリとして、amazon-ecs がある。

今回ライブラリを新たに開発した動機は、大きく 3 つある。前半の方は個人的な動機で、後半の方はより社会的な動機と言える。

  • API の仕様や振る舞いを調べながら開発することで、API への理解を深めたかった
  • レスポンスの内容を解釈して Ruby として適切なインターフェースで取り出すところまでサポートしたかった
  • レスポンスの内容を取り出す機能を細かく用意することで、動作するドキュメントとしての側面を持ちたかった

これまでも https://amakan.net/ の開発で Amazon Product Advertising API には amazon-ecs を利用してお世話になっていたが、ドキュメントの量も多く、複雑で、果たして適切な使い方が出来ているのかどうか不安だった。今回腰を据えてライブラリをつくることで、ドキュメントや実際の API の挙動の調査にきちんと向き合い、いままで把握できていなかったところも正確に理解できるようになったと思う。

ライブラリの使い方

いま現在開発しているライブラリでは、いまのところ、大きく分けて 2 通りの使い方がある。

  • ASIN コードを与えて検索する
  • キーワードを与えて検索する

ASIN コードを与えて検索する

予め ASIN コードが分かっている場合、そのコードを与えて商品を検索するという API 呼び出しに対応した機能。ASIN コードというのは、Amazon の商品ごとに固有の10桁の ID であり、書籍の商品においては 10 桁表現の ISBN コードと同じものになる。ISBN コードが既に分かっている場合や、既に取得済みの商品データに更新が無いか調べるときなどに利用できる。

例えば、10桁表記の ISBN コードが「4041054443」の本のタイトルをライブラリを利用して調べてみる。

require "rapa"
client = Rapa::Client.new(access_key_id: "...", secret_access_key: "...", associate_tag: "...")
response = client.list_items(domain: "co.jp", asins: ["4041054443"])

Amazon Product Advertising API の利用には、アクセスキー ID、シークレットアクセスキー、アソシエイトタグの発行が必要になる。これらはどれも、Amazon アソシエイトの管理画面から発行できる。

domain に "co.jp" という値を渡しているが、これは日本の Amazon (amazon.co.jp) を対象に検索するように命令しており、この指定は必須である。ASIN コードは asins という名前で配列で指定しているが、1度のリクエストで最大 10 件までの検索結果を取得できるため、配列で指定するようなインターフェースになっている。

item = response.first

レスポンスは、商品の集合として扱いやすいように、 Enumerable のインターフェースを実装している。今回は結果は 1 件しか存在しないはずなので、先頭の要素を取り出すことにする。

puts item.title

商品のタイトルは #title メソッドで取り出せる。出力結果は以下の通り。

けものフレンズBD付オフィシャルガイドブック (1)

キーワードを与えて検索する

検索キーワードを与えて商品を検索するという API 呼び出しに対応した機能。

先程の例とは逆に、今度は「けものフレンズBD付オフィシャルガイドブック」というキーワードを元に商品を検索してみる。

response = client.search_items(domain: "co.jp", keywords: ["けものフレンズBD付オフィシャルガイドブック"])

今回は #search_items というメソッドを利用し、keywords という値で検索キーワードを与えている。さて、検索結果は複数件になるが、前述の通りレスポンスは Enumerable のインターフェースを実装しているということで、ここでは Enumerable#map を利用してタイトルだけを羅列してみることする。

puts response.map(&:title)

結果は以下の通り。

けものフレンズBD付オフィシャルガイドブック (1)
けものフレンズBD付オフィシャルガイドブック (2)
けものフレンズBD付オフィシャルガイドブック (3)
けものフレンズBD付オフィシャルガイドブック (6)
けものフレンズBD付オフィシャルガイドブック (5)
けものフレンズBD付オフィシャルガイドブック (4)
けものフレンズBD付オフィシャルガイドブック (1)(Blu-ray Disc)
けものフレンズ ‐ようこそジャパリパークへ!‐(1)<けものフレンズ ‐ようこそジャパリパークへ!‐> (角川コミックス・エース)
ようこそジャパリパークへ(初回限定盤)
ようこそジャパリパークへ(通常盤)

利用にあたっての前提・仮定など

実装にあたって Ruby 2.3 からの新機能である Hash#dig を試してみたので、このライブラリを使うには Ruby 2.3 以降が必要になる。また、HTTP クライアントとして Faraday、XML パーサとして MultiXML が実装に利用されているので、これらのライブラリに依存していることは注意されたい。

想定する利用者

https://amakan.net/、及び現在開発中の amakan video で利用するために開発したので、主な利用者は自分だろうが、Amazon Product Advertising API を利用する他の開発者が再利用できる実装にしたいとも考えている。如何せん API の仕様が大きく、開発者が利用していないが故に実装されていないという機能が沢山あるので、現実的なユースケースを収集することがライブラリの成長に繋がると思う。

何が達成できたらゴールか

ライブラリを開発するときは「どこまでやるか」というのを決めておいた方が、利用者視点では更新されず、開発者視点では要望に対応できずという宙ぶらりな状態になることが防げると思っている。今回の場合、このライブラリを利用して amakan と amakan video を稼働させられるところまで持っていければ、ライブラリのショーケースの 1 つにもなるし、ひとまずのゴールになると考えている。