概要
以前使用したAmazon APIについてまとめておきたいな〜と思いまして。。。。。
実際に導入から実装までの流れを含め、簡単な書籍検索アプリを作ってみました!
作成するアプリの内容としては、
検索ボックスにキーワードを書き込み、その検索結果を返してくれるというシンプルなものです!
さらに!
おまけとしてJSを適用させて、インクリメンタルサーチを行えるようにもしたいと思います!
環境
Ruby 2.1.3
Rails 4.2.4
目次
- アプリケーションの作成,基本的な実装
- AmazonアソシエイトIDとAccess Keyの取得
- Amazon APIを実際を使用して書籍検索機能の実装
- インクリメンタルサーチの実装
実装
1. アプリケーションの作成,基本的な実装
アプリケーションの作成、routing, controllerの作成,viewの作成を行います。
1.1 アプリケーションの作成
書籍検索アプリなので、アプリ名はbook_search
とします。
$ rails new book_search
$ cd book_search
現在の最新版(2015年12月)のgem mysql2
のバージョンだとエラーが生じるので、バージョンを書き換えます。
デバックの際に使用するpry-rails
を入れておきましょう。
gem 'mysql2', '0.3.18'
gem 'pry-rails
DBの作成を行っておきます。
$ bundle install
$ rake db:create
1.2 基本的な実装
コントローラー、モデルの作成を行いましょう。
controller名は、books_controller
とします。
ヘルパーとアセットファイルを生成する必要がないので、オプションをつけて作成しないようにします。
また、モデルに関しては、DBへのアクセスは必要がないので、ActiveRecordを継承しないモデル(参考サイト)を作成します。
$ rails g controller books --assets false --helper false
では、ルーティングの設定, コントローラーにおけるアクションの定義、viewの編集を行いましょう。
ここも基礎の部分なので、説明は省略させていただきます。
Rails.application.routes.draw do
root to: 'books#search'
end
class BooksController < ApplicationController
def search
end
end
class Book
# プロパティの設定
attr_accessor :title, :image_url, :url
def initialize(title, image_url, url)
@title = title
@image_url = image_url
@url = url
end
end
<div class='content'>
<div id="search-box">
<%= form_tag('/', method: :get) do %>
<%= text_field_tag :book, "", id: "book_search", name: "keyword", placeholder: "キーワードを打ち込んでください", style: "width: 200px;"%><button title="検索" type="submit">検索</button>
<% end %>
</div>
<h2>検索結果</h2>
<div id='book_list'>
<!-- コメントアウトしておく -->
<!-- <%= render partial: 'book_list' %> -->
</div>
</div>
<% if @books.present? %>
<% @books.each do |book| %>
<div class="list">
<%= link_to (image_tag(book.image_url, style: "width: 70px;height: 100px;display: inline-block;")), book.url %>
<%= book.title %>
</div>
<% end %>
<% end %>
2. AmazonアソシエイトIDとAccess Key IDの取得
Amazon APIを使用するにあたって、以下のキーが必要となります。
- associate_tag
- AWS_access_key_id
- AWS_secret_key
associate_tag
はAmazonアフィリエイトアカウントを登録することで、取得できます。
また、AWS_access_key_id
とAWS_secret_key
はProduct Advertising APIに登録することで取得することができます。
何か分からないことがありましたら、こちら(Access Key IDとSecret Access Keyの取得)を参照ください。
2.1 AmazonアソシエイトIDの作成
AmazonアソシエイトIDの作成はこちらから行いましょう。
このとき、AmazonアソシエイトIDはログインページの右上のあるのが、覚えておいてください。
2.2 Product Advertising API
アカウント作成
Access Keyを取得するためには、Product Advertising API
アカウント作成を行う必要があります。
先ほど登録したAmazonアソシエイトのページから
以下の写真のようにメニュータブのProduct Advertsing API
をクリックしてアカウント作成ボタンをクリックします。
注意点としては、
- Amazonアソシエイトで使用した同じメールアドレスを指定すること。
- すべて英語で入力すること。
です。
2.3 Access Key ID
とSecret Access Key
の取得
登録が完了できたら以下のようにして、2つのAccess Keyを確認することができます。
注意として、シークレットキーは絶対に公開にしないようにしてください。
3 Amazon APIを実際に使用する
ついにAmazon APIを使用する下準備が整いました!!
これらカリカリとコードを書いていきます!!!
APIを使用し検索結果を表示するにあたって、以下の手順を踏みます。
- gemの
amazon-ecs
の追加、設定ファイルの記述 - コントローラーの編集
- Viewに検索結果を表示
3.1 gemのamazon-ecs
の追加、設定ファイルの記述
Amazon APIを使用するにあたって、amazon-ecs
というgemを使用します。(リポジトリはこちら)
gem 'amazon-ecs'
config/environment.rb
にて、gemでインストールしたAmazon::Escを読み込みAmazon Web Serviceを利用するためのAPI Key設定します。
自身のアソシエイトキーとアクセスキーを指定します。
Amazon::Ecs.options = {
associate_tag: '**************',
AWS_access_key_id: '*****************',
AWS_secret_key: '***********************'
}
$ bundle install
3-2 コントローラーの編集
ここからAmazon Web Serviceにアクセスするための記述を行っていきます。
ソースコードは以下になります。
class BooksController < ApplicationController
def search
if params[:keyword].present?
# デバックログ出力するために記述
Amazon::Ecs.debug = true
# Amazon::Ecs::Responceオブジェクトの取得
books = Amazon::Ecs.item_search(
params[:keyword],
search_index: 'Books',
dataType: 'script',
response_group: 'ItemAttributes, Images',
country: 'jp',
power: "Not kindle"
)
# 本のタイトル,画像URL, 詳細ページURLの取得
@books = []
books.items.each do |item|
book = Book.new(
item.get('ItemAttributes/Title'),
item.get('LargeImage/URL'),
item.get('DetailPageURL'),
)
@books << book
end
end
end
end
ひとつひとつ説明していきたいと思います。
Amazon::Ecs.debug = true
有効にすることで、以下の写真のように、デバックログが出力され、検索するにあたってどのような指定を行っているのか、また、エラー時にはエラー内容が出力されます。
さらに注目すべきは、amazon-ecs
がリクエストしたURLも出力されているので、URLからAPIのリクエストの実行結果も見ることができます。
Amazon::Ecs::Responseオブジェクトの取得
item_searchメソッド
幾つかの検索条件を満たす商品のXML要素の情報を配列として返します。
また、一度の検索に検索に最大10個の検索結果を返します。
今回の指定した引数に関しての説明をしていきたいと思います。
-
第一引数
に、自身が打ち込んだキーワード -
第二引数
のseach_indexにて検索対象の指定を行う。Books
としているので、検索対象は本としている。詳しくは、パラメータの組み合わせはこちらを参照してください。 -
第三引数
のresponce_groupでは、レスポンスの情報量を制御します。情報量を適切に保つには、ご使用のアプリケーションが必要とする情報だけを返すレスポンスグループを指定します。
商品の詳細情報と画像情報が欲しいのでItemAttributesとImage
を指定します。
詳しいレスポンスグループの指定はこちら。 -
第四引数
のcountryには地域の指定をします。 -
第五引数
のpower: "Not kindle"
と指定することで、検索結果からkindleの除外することがすることができます。参考URL:kindleを検索結果から除外する
ほかにも色々なオプションがありますので、気になる方はご自身で調べてみてください。
本のタイトル,画像URL, 詳細ページURLの取得
Amazon::Ecs::Responseのインスタンスbooksから必要な情報を取得します。
今回必要な情報は、タイトル,画像URL,詳細ページのURLです。
変数のbooksがどのような構造をしているか確認したい場合には、binding.pry
を使用する、あるいは、コンソールで出力されているAPIリクエストのURLから確認することができます。
必要な要素の取得はget
メソッドを使って取得できます。
取得結果をインスタンス変数@booksに渡してviewに渡すことができます。
Viewに検索結果を表示
search.html.erb
のコメントアウトしていた箇所を解除してみましょう。
こんな感じになりましたか??
ひとまずはAmazon APIの導入から実装までは以上です!
4. インクリメンタルサーチの実装
ここは主題ではないので、簡単にソースコードの紹介とさせていただきます。
インクリメンタルサーチを行うにあたって、以下のファイルを生成、編集します。
- incremental_search.js
- search.js.erb
incremental_search.jsはassets/javascripts/
に置き、
search.js.erbはview/books/
に置きます。
では、jsをカキカキしていきましょう。
下に示すソースコードはあくまでも一例です。
$(window).on('load', function() {
var timer;
var preInput = "";
ajaxSearch = function(input) {
$.ajax({
url: "/",
type: "GET",
dataType: 'script', // jsファイルを指定したいので、dataTypeをscriptに指定
data: ("keyword=" + input)
});
};
triggerAjax = function(input) {
if(preInput !== input){ //文字列が変更ときのみメソッド実行する
clearTimeout(timer);
timer = setTimeout(ajaxSearch, 500, input); // 処理を500ms毎に実行
};
};
$('#book_search').on('keyup', function() {
input = $.trim($(this).val()); // 文字列の先頭と末尾の空白を削除
triggerAjax(input);
preInput = input;
});
});
$("#book_list").html("<%= j(render 'book_list') %>");
これで検索ボタンをいちいち押す必要がなくなり、検索もスイスイ行うことが可能です!
完成!!