[Ruby] [Rails] Search books with Amazon PA API

3 minute read

It’s a little troubled with Amazon’s book search API, so take a note. I couldn’t find any other Japanese article, so I hope you find it useful.

Introduction

Although APIs such as Google and Amazon can be used to search for books, I decided to use Amazon’s PA (Product Advertising) API because Google (Google Books API) had some unsatisfactory parts.

However, from April 2020, the version of PA API has changed, and it will not work if you use the Amazon-ecs gem method… (I referred to the method of this article,butcouldnotgetthedata…)

Looking at reference of amazon-ecs,itwaswrittenthatitisgoodtouseanothergem(paapi), so I decided to try it. .. Reference of paapi

By the way, in order to use this API, it is necessary to register and apply for Amazon Associate first, so if you have not done so, please click this article Please refer. The hurdles for judging are relatively high, so I think that those who want to use it immediately are tough. (It took me about a month)

Complete image

The image of the completed search looks like this. You can see that you can get the image and URL properly. 85a1b44b0aecfa2b419158ec43da4af8.gif

Implementation policy

This time we will implement the following processing

  1. Enter the keyword in the form and send the request
  2. Search by keyword entered by hitting API
  3. Process the response from API and display the data

Various files

Gem

Gemfile


gem'paapi'

Don’t forget to bundle install. (Don’t forget to restart if the server is running)

config

Create paapi.rb directly under config/initializers and write the key and ID settings. ・Access_key: Access key ・Secret_key: Secret key ・Partner_tag: Associate ID (your ID ending in 22)

config/initializers/paapi.rb


Paapi.configure do |config|
  config.access_key = Rails.application.credentials[:pa_api][:access_key_id]
  config.secret_key = Rails.application.credentials[:pa_api][:secret_key]
  config.partner_tag = Rails.application.credentials[:pa_api][:associate_tag]
end

In my case, I call it from credentials and use it. (Somehow I hate it if it leaks) If you do not know how to use credentials, please refer to here.

Controller

This time it’s a sample, so I made a searches controller. Actually, it is better to create it in the book directory to make it easier to understand what the search is.

terminal


$ rails g controller searches

searches_controller


class SearchesController <ApplicationController
  before_action :call_client, only: :index
  
  def index
    si = @client.search_items(keywords: keyword_params, SearchIndex: "Books")
    @items = si.items
  end
  
  private
  
  def call_client
    require'paapi'
    @client = Paapi::Client.new(access_key: Rails.application.credentials[:pa_api][:access_key_id],
                                secret_key: Rails.application.credentials[:pa_api][:secret_key],
                                market: :jp,
                                partner_tag: Rails.application.credentials[:pa_api][:associate_tag])
  end
  
  def keyword_params
    params.require(:keyword)
  end

end

I create an instance of client and apply the search method to it to get the product information. This time, the genre is limited to books by product search, but you can specify the product number to obtain information or specify another genre, so please use it according to your purpose.

When you search for products, 10 items of data will be acquired and will be the data of the response class. Since the data of items is contained in this, you can handle it as data of the Item class by extracting it with .items. (The Item class is provided by gem, and you can use convenient methods. We will explain it later.)

Routing

Don’t forget to set it.

routes.rb


Rails.application.routes.draw do
  # (Omitted)
  resources :searches, only: [:index]
end

view file

First, prepare a search form.

Search form


.book-search
  = form_with url: {controller:'searches', action:'index' }, method: :get, local: true do |f|
    = f.text_field :keyword
    = f.submit "Search"

It is a page that displays the data retrieved by the next search. This time, display it in searches/index.

views/searches/index


- @items.each do |item|
  .url
    = "url: #{item.detail_url}"
  .title
    = "title: #{item.title}"
  .author
    -authors = item.contributors.select {|e| e['RoleType'] == "author" }&.map {|e| e.dig('Name') }&.reject {|n| n.to_s .empty?}
    = "author: #{authors[0]}"
  .image
    = image_tag "#{item.image_url}", height: '170px', width: '120px'
  .asin
    = "asin: #{item.asin}"

By using the title method, detail_url method, and image_url method, you can easily get the product title, URL, image, etc. from the data of the Item class.

You can get many other things, so I think it’s better to try it by looking at the Reference.

By the way, authors did not work even if I followed the reference (using the authors method), so I adjusted it myself. (I have to find the one whose RoleType is author, but the prepared method is looking for the one whose Role is Author)

Reference

・Scratchpad It is a page where you can try what kind of data is obtained by hitting the API. Https://webservices.amazon.co.jp/paapi5/scratchpad/

・API reference Official reference for Product Advertising API 5.0. Https://webservices.amazon.com/paapi5/documentation/api-reference.html