Jan 25

以前、ふと思い立ってamazonのアソシエイト・プログラムに申し込み、アソシエイトリンクを張ってみた。

が、やってみてすぐにいくつかの点で不満を感じていた。

  1. amazonが用意したテンプレートの情報だけではいまいち物足りない。たとえば出版社の情報とかランキング情報なども表示させたい。
  2. Amazonのテンプレートはiframe要素を使ってるので、firefoxのnoscriptと相性が悪い(詳細は後述)。iframeはHTML標準の将来的に廃止の方向だという点でもいまいち。

不満を解消するべくいろいろ試行錯誤した挙げ句、結局Amazon Web Services(AWS)デビューを果たし、Amazon Associates Web ServiceのRESTインタフェース経由で得られる基本的な情報を整形して埋め込み、さらにランキングとかレビューとかの動的に変わり得る情報は閲覧のたびにRESTを叩いて自動的に更新する、という方法に行き着いた。見た目はこんな感じ:

IPv6 Advanced Protocols Implementation (The Morgan Kaufmann Series in Networking)

IPv6 Advanced Protocols Implementation (The Morgan Kaufmann Series in Networking)
Qing Li, Jinmei Tatuya, Keiichi Shima
Morgan Kaufmann, 2007-04-20

Amazonランキング: 499520
Amazonおすすめ度: amazon rating 5.0

amazon rating 5
Getting Intimate with IPv6
amazon rating 5
IPv6 Advanced Protocols Implementation
amazon rating 5
Excellent way to complete the story...

さらに、スクリプトとか「自動的に裏でごそごそされること」とかが嫌いな人向けに自動更新をするかどうかを選択できるようにした上で、デフォルトでは更新しないようにしておいた。それでも、書名とか著者名などの一般的な情報はもともと埋め込まれているので表示可能という点がiframeを利用した場合と違っている。

自動更新が有効な場合、AWSのRESTリクエストにXSLTを指定できる機能を利用して、応答をJSON形式で取得し、その内容に基づいて該当する部分のDOMを書き換えている。

上の例におけるRESTリクエストはこんな感じ:

  http://xml-us.amznxslt.com/onca/xml?
  Service=AWSECommerceService
  &Version=2008-08-19
  &Operation=ItemLookup
  &AssociateTag=jinmeiorg-22
  &AWSAccessKeyId=0MCVGB7CBWR8Z52PVZG2
  &IdType=ASIN
  &ResponseGroup=Large
  &ItemId=0123704790
  &Style=http://www.jinmei.org/xslt/aws20080819-lookup-jsonp.xsl

最後の”Style=”に続くURLが変換用のXSLT。

また、ページ内に複数の書籍情報が含まれている場合に備えて、10 item分(AWSの仕様上の上限)までをまとめてRESTのリクエストとして発行する。さらに、JPとUSが混ざっているような場合(サーバのFQDNが違うのでリクエストを分ける必要がある)や、万一10 itemでも足りない場合に備えて、複数回のリクエストを出せるようにし、さらにその際にAWSの「1コール/秒ルール(AWS agreementの5.1.19に記載)」に反しないように、リクエスト間を少なくとも1秒ずつ開けるようにしている。(全部終わるまでの間にページを閉じられてしまうということもないとはいえないが、ここでの利用形態からするとそもそも複数回のリクエストが必要になるようなケース自体が稀だろう)。

当然、同じようなことをしたいと考える人は多いようで、ちょっと検索すると似たような仕掛けがたくさん引っ掛かる。たとえばG-Toolsが生成するテンプレートは見た目についてはかなり期待するイメージに近く、Ajax Amazonというスクリプトを使うとAWS経由で(一部)自動更新もしてくれるようではあるのだが、結局できあいのツールを使わずに自作することにした。G-Toolsで不満だったのは以下のような点:

  • 複数の国(といっても実用上USとJPくらいだけど)の情報を同時に扱えるかどうかがよくわからない
  • また、複数の国を扱えるとしても、「1コール/秒ルール」に反しないようにupdateできるのかどうかが不明
  • スタイル的にtableを使ってレイアウトしているのがweb標準原理主義的にちょっと気持ち悪い
  • 外部のツール(jQuery)に依存している。依存性自体を少なくとしたいというのと、第三者(この場合Amazon)が提供する情報をもとに自分のページを書き換えるという動作をすることから、セキュリティ上なるべく中身がちゃんとわかっている部品を使いたい。

まあ、実際には自分でRESTfulなアプリケーションを使って遊んでみたかっただけという話もある。

完全自作とか外部ツールの流用以外にも、RESTで指定するXSLTで直接好みのスタイルのhtmlに変換するようにして、その内容を貼り付けるという方法もある。実際、自動更新前の基本情報の部分はこの方式で生成している。たとえば、以下のhtmlを直接吐くRESTリクエストをクリックすれば、上の例と同じ内容が独立したページとして表示される。

ただし、貼り付けっぱなしだと、当然ながら可変の情報は更新されない。AWS agreementの5.1.15,5.1.16あたりからすると、AWSから持ってきた情報は定期的に最新の状態にすることが要求されているので、それに反することになりそうなのがちょっと気持ち悪い。代替案として、iframe(もしくはweb標準原理主義的にはobject)要素の中にリンクを埋め込む方法も考えられる。この場合、ページをロードするたびに最新の情報が表示されるようになる。object要素を使った例は以下の通り。data属性でREST用のURLを指定している。

この方法が一番手間と効果のバランスが取れているような気はするが(とはいっても変換用のXSLTを書くのはそれなりの仕事だが)、上述の通りobject要素を使うとfirefoxのnoscriptとの相性が悪いという欠点がある。ちなみに、amznxslt.comを許可サイトとして明示的に指定しないと、こんな感じののっぺらぼうになってしまい、かなり寂しい:

また、AWSのサーバにXSLTのURLを渡して変換してもらう場合一般の問題として、どうもたまに変換にしくじることがあるっぽい。そうすると当然object(またはiframe)として表示される内容も意味不明になってしまう。

他にも、個別のobjectごとにHTTPのリクエストを出すことになるから、複数のitemが含まれている場合は例によって1コール/秒問題に引っ掛かるおそれがあるという欠点もある。

…というように、いろいろtry & errorを繰り返していてずいぶん時間がかかってしまったが、ようやく作業完了。これで安心して読書に励める(本末転倒)。

コメント 4 件

  1. sumikawa Says:

    このページだけだと思うけど、body要素がネストになってます。
    読書記録の方はそうなってないので、try&error時のゴミかと思いますが。

    HTMLソース読んで勉強しようと持ったら、bodyがネストになってて、ええええと思った次第です。

  2. jinmei Says:

    > このページだけだと思うけど、body要素がネストになってます

    おっとほんとですね。ネストというか、tagを閉じてもいないので単なるゴミになってましたね…。

    ご指摘ありがとうございます。直したつもりです。

  3. sumikawa Says:

    89行目にまだありまーす。

  4. jinmei Says:

    あれ、すみません。確かに問題の個所を消したつもりだったんですが、保存に失敗したのかも。今度こそ。

コメントを投稿 / Submit Comments


Warning: Undefined variable $user_ID in /usr/home/jinmei/src/itheme/comments.php on line 74



(あれば / Optional):