ひげろぐ

技術者として仕事人としての思うところや覚え書きやらです
Home      Profile      Works     
2009-07-28

遅ればせながらAmazonのAPIの認証に対応中

ガン無視してたらここんとこAmazonからメールでせっついてきたりして、早いところ対応しやがれよコノヤローって気配です。

導入の意図がまだよくわかってないのだけど、何なのかな。
利用状況を厳密に把握して何かやりたい?

ともあれ対応自体はもうRubyのサンプルコードもいろいろと出ていて簡単だった。
既存のURLから機械的に変更するのも簡単なので大した対応コストは取られない。

主に参考にしたのは以下。感謝です。

多少引っかかったのは以下の点だけ。

TimeStampじゃなくてTimestamp

TimeStampだと400 Bad Request

単なる自分のタイポ。

ホストにhttp://は不要

「http://ecs.amazonaws.jp」で計算してたら403 Forbidden。
「SignatureDoesNotMatch」だそうだ。

引っかかったときに一応公式のドキュメントも見たけど、これはそんなにがっつり理解しなくても動けばいいもんだと思う。

2008-03-20

Amazon WebサービスのレスポンスをActiveRecordでキャッシュ

前回RailsでAmazonのWebサービスを使ってみたけれども、何かあるたびに毎回リクエストを送るのはいろいろ無駄があって忍びないのでレスポンスをキャッシュしなければならない。

ということで今回はActiveRecordを使ってざっくりキャッシュしてみる。
キャッシュテーブルにたくさんカラムを定義するのは面倒なので検索キーにしたいものだけカラムとして定義して、あとは結果をシリアライズして突っ込む方針で。

キャッシュ用のテーブルとモデルを作る

まずはキャッシュするためのテーブルとモデルを準備。

テーブル

とりあえずマイグレーションでテーブルを作る。

class CreateAmazonCaches < ActiveRecord::Migration
  def self.up
    create_table :amazon_caches do |t|
      t.string :asin
      t.string :title
      t.text :response_dump

      t.timestamps
    end
  end

  def self.down
    drop_table :amazon_caches
  end
end
モデル

キャッシュを参照するためのモデル。
データを参照するときにレスポンスの内容をデシリアライズする。

class AmazonCache < ActiveRecord::Base
  @reponse_hash = nil
  @search_limit = 10

  def get(name)
    @response_hash = Marshal.restore(response_dump) if @response_hash.nil?
    @response_hash[name.to_sym]
  end

  def self.search(title, order = 'id', limit = nil)
    @search_limit = limit if limit
    self.find(:all, :conditions => ["title like ?", "%#{title}%"], :order => order, :limit => @search_limit)
  end
end

ハッシュのデシリアライズのタイミングはafter_findでもいいかもしれないなぁ。

キャッシュの保存と参照

テーブルとモデルができたので次はそれを使って実際にキャッシュする。

レスポンスをキャッシュする

以下がレスポンスをキャッシュするためのコード。

get_hashで取得したデータのハッシュだけシリアライズして突っ込む。
(itemのままだとなにやらうまいことMarshalでシリアライズできなかった)

res = Amazon::Ecs.item_search("Rails", :response_group => 'Large')
res.items.each do |item|
  AmazonCache.create(:asin => item.get('asin'), :title => item.get('title'), :response_dump => Marshal.dump(item.get_hash))
end
キャッシュを参照する

参照は以下のように。

items = AmazonCache.search("Rails")
items.first.get(:title) # => Railsの何かの本とかそんなタイトル

smallimageのように子要素を持つ要素はXMLの断片が保存されている。

items.first.get(:smallimage) # => "<url>http://ecx.images-amazon.com/images/I/hogehogehoge-.jpg</url><height units=\"pixels\">75</height><width units=\"pixels\">58</width>"

これは正規表現とかで値を取り出すのが楽かね。
モデルにそれ用のメソッドを追加してしまってもいいかもしれない。

まあひとまず今回はこんなところで。

2008-03-17

RailsでAmazon Webサービス

以下のページを参考にAmazon WebサービスにRailsからアクセスしてみた。
かなり楽ちん。

RoRでAmazon Associate Web Serviceを使う : Mashupを作ろう : 記事 : MASHUPEDIA – マッシュペディア – : Web API x Mashup

前準備

まずamazon-ecsというライブラリをgemで入れる。

$ sudo gem install amazon-ecs

次にRailsのconfig/environment.rbの末尾にamazon-ecsのオプションの設定を書く。

require ‘amazon/ecs’

Amazon::Ecs.options = {
  :aWS_access_key_id => "hogehogehoge",
  :associate_tag => "stepfeed-22",
  :country => :jp
}

アソシエイトIDも設定できる。

あとはRailsのどこでもamazon-ecsを使ってAmazonのデータを検索可能。

使い方

検索

Amazon::Ecsのitem_searchというメソッドを使うとAmazon Webサービスにアクセスしてレスポンスを取得する。
レスポンスはAmazon::Ecs::Responseオブジェクトになって返される。

res = Amazon::Ecs.item_search("Rails")

これだとタイトルやASINなどの基本的なデータしか取得できない。
簡単なテキストリンクを作るだけならそれだけで十分だが、画像やユーザーレビューなどの詳細なデータを取得したい場合は:reponse_groupオプションでMediumとかLargeとか指定して検索する。

res = Amazon::Ecs.item_search("Rails", :response_group => 'Large')

:sortオプションでソート条件指定も可能。

res = Amazon::Ecs.item_search("Rails", :sort => 'titlerank')
データの参照

検索したデータは返されたAmazon::Ecs::Responseオブジェクトのitemsという変数に入っている。
itemsはAmazon::Elementオブジェクトの集まり。

Amazon::Elementは個別のAmazon商品情報を持っている。
getメソッドを使うと特定の項目のデータを取得できる。

res.items.first.get(:title)

またget_hashメソッドを使うとデータをハッシュで取得できる。
ハッシュになるとキーはシンボルになるので、文字列で指定しないように注意。(getメソッドの引数は文字列でもシンボルでも可)

data = res.items.first.get_hash
data[:title] # => なんかのタイトル
data['title'] # => nil 
子要素を持ったデータの参照

smallimageなどいくつかの情報は子要素を持っているがgetで参照するとXMLの断片が文字列で返ってくる。

res.items.first.get(:smallimage) # =>
"<url>http://ecx.images-amazon.com/images/I/hogehogehoge-.jpg</url><height units=\"pixels\">75</height><width units=\"pixels\">58</width>"

子要素を参照するにはget_hashを使うと便利。

data = res.items.first.get_hash(:smallimage)
data[:url] # => "http://ecx.images-amazon.com/images/I/hogehogehoge-.jpg"

参考

amazon-ecsのRDoc

Sortパラメータ : ええもん屋 ラボ

検索結果のソート(Sort) – Amazon Web サービス

追記

ActiveRecordを使ってレスポンスをキャッシュする手順をまとめてみた。

copyright brass.to | powered by WordPress ME