[RUBY] [Rails] Book search with Amazon PA API

I made a note because it was a little difficult with Amazon's book search API. I couldn't find any other articles in Japanese, so I hope you can refer to them.

Introduction

You can use APIs such as Google and Amazon to search for books, but I decided to use Amazon's PA (Product Advertising) API because Google (Google Books API) was not enough.

However, the version of PA API changed from April 2020, and the method using the gem of amazon-ecs does not work ... (I referred to the method of this article, but I could not get the data ...)

Looking at Amazon-ecs reference, it says that it is better to use another gem (paapi), so I decided to use it. .. Paapi Reference

By the way, in order to use this API, you need to register and apply to Amazon Associate first, so if you haven't done so already, please read this article. Please refer. The hurdles for judging are relatively high, so I think it's tough for those who want to use it immediately. (It took about a month for me)

Complete image

The completed image of the search looks like this. You can see that the images and URLs have been acquired properly. 85a1b44b0aecfa2b419158ec43da4af8.gif

Implementation policy

This time we will implement the following processing

  1. Enter keywords in the form and submit a request
  2. Hit the API and search by the entered keyword
  3. Process the response from the API and display the data

Various files

Gem

Gemfile


gem 'paapi'

Don't forget to bundle install. (If the server is running, don't forget to restart it)

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. (Because I hate it when it leaks) If you don't know how to use credentials, please refer to here.

controller

Since this is a sample, I created a searches controller appropriately. Actually, it is better to create it in the book directory so that you can easily 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 a search method to it to get product information. This time, the genre is limited to books in the product search, but you can specify the product number to get information or specify another genre, so please use it properly according to the purpose.

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

routing

Don't forget to set it.

routes.rb


Rails.application.routes.draw do
  # (Abbreviation)
  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"

Next is the page that displays the data obtained by searching. This time, it will be displayed 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 Item class.

You can get many other things, so I think you should try it by looking at Reference.

By the way, authors didn't work according to 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 acquired 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

Recommended Posts

[Rails] Book search with Amazon PA API
[Rails] Book search (asynchronous communication) with Amazon PA API v5.0
API creation with Rails + GraphQL
Timeless search with Rails + JavaScript (jQuery)
Rails API
Rails6 [API mode] + MySQL5.7 environment construction with Docker
[Java] Get images with Google Custom Search API
Let's make a search function with Rails (ransack)
How to build API with GraphQL and Rails
Implement search function with Rakuten Books (DVD) API
Using PAY.JP API with Rails ~ Implementation Preparation ~ (payjp.js v2)
Build Rails (API) x MySQL x Nuxt.js environment with Docker
Using PAY.JP API with Rails ~ Card Registration ~ (payjp.js v2)
Compatible with Android 10 (API 29)
Rails deploy with Docker
[Rails] Implement search function
Handle devise with Rails
[Rails] Learning with Rails tutorial
[Rails] Test with RSpec
Rails search function implementation
[Rails] Development with MySQL
Supports multilingualization with Rails!
Double polymorphic with Rails
[Rails] Create API to download files with Active Storage [S3]
Try hitting the zip code search API with Spring Boot
[Rails] Search from multiple columns + conditions with Gem and ransack