Rails MWS 商品情報の取得

# はじめに
MWSで商品情報を取得できるオペレーションには以下のようなものがあります。

- [ListMatchingProducts](http://docs.developer.amazonservices.com/ja_JP/products/Products_ListMatchingProducts.html)
- [GetMatchingProduct](http://docs.developer.amazonservices.com/ja_JP/products/Products_GetMatchingProduct.html)
- [GetMatchingProductForId](http://docs.developer.amazonservices.com/ja_JP/products/Products_GetMatchingProductForId.html)

この3つはレスポンスは同じですが、以下のような違いがあります。

|オペレーション|役割|最大リクエストクォータ|回復レート|時間あたりのリクエストクォータ|
|:--|:--|:--|:--|:--|:--|
|ListMatchingProducts|検索クエリに応じた、商品およびその属性のリストを返します。|20リクエスト|5秒あたり1回のリクエスト|1時間あたり720リクエスト|
|GetMatchingProduct|ASINのリストに応じた、商品およびその属性のリストを返します。|20リクエスト|1秒あたり2商品|1時間あたり7200リクエスト|
|GetMatchingProductForId|ASIN、GCID、SellerSKU、UPC、EAN、ISBN、およびJANのリストに応じた、商品およびその属性のリストを返します。|20リクエスト|1秒あたり5商品|1時間あたり18000リクエスト|


今回は``GetMatchingProductForId``を使用して商品情報を取得します。

# 実装

## 事前準備
[Rails MWS APIを利用するまでの事前準備](https://qiita.com/ayies128/items/7ce8530574122dfec507)
こちらよりpeddlerのclientインスタンスを作成できる状態にしておいてください:point_up:

## リクエストの送信
peddlerのclientインスタンスを使用すればリクエストを送信することはとても簡単です:baby:

リファレンスではこう書いてあります。[リファレンス](http://www.rubydoc.info/gems/peddler/MWS/Products/Client#get_matching_product_for_id-instance_method)
``get_matching_product_for_id(id_type, *ids, opts = { marketplace_id: primary_marketplace_id })``

``id_type``で選択できるのは、``SellerSKU、UPC、EAN、ISBN、JAN``の何か、
そして``ids``は``id_type``で選択したコードを最大で5つ設定できます。

なので、これだけでリクエストを送ることができますね。

```rb
client = MWS.products( 
  # 省略
)

id_type = 'EAN'
ids = ['4545784064849', '4571368442307']

client.get_matching_product_for_id(id_type, ids)
```

レスポンスは以下の通りです。

```xml
<?xml version="1.0"?>
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductForIdResult Id="4545784064849" IdType="EAN" status="Success">
  <Products xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
    <Product>
      <Identifiers>
        <MarketplaceASIN>
          <MarketplaceId>A1VC38T7YXB528</MarketplaceId>
          <ASIN>B06XKNN3L2</ASIN>
        </MarketplaceASIN>
      </Identifiers>
      <AttributeSets>
        <ns2:ItemAttributes xml:lang="ja-JP">
          <ns2:Binding>おもちゃ＆ホビー</ns2:Binding>
          <ns2:Brand>マックスファクトリー</ns2:Brand>
          <ns2:ItemDimensions>
            <ns2:Height Units="inches">10.24</ns2:Height>
            <ns2:Length Units="inches">5.51</ns2:Length>
            <ns2:Width Units="inches">3.94</ns2:Width>
          </ns2:ItemDimensions>
          <ns2:IsAdultProduct>false</ns2:IsAdultProduct>
          <ns2:Label>Max Factory</ns2:Label>
          <ns2:Languages>
            <ns2:Language>
              <ns2:Name>japanese</ns2:Name>
              <ns2:Type>Unknown</ns2:Type>
            </ns2:Language>
          </ns2:Languages>
          <ns2:ListPrice>
            <ns2:Amount>5800.00</ns2:Amount>
            <ns2:CurrencyCode>JPY</ns2:CurrencyCode>
          </ns2:ListPrice>
          <ns2:Manufacturer>Max Factory</ns2:Manufacturer>
          <ns2:Model>M06484</ns2:Model>
          <ns2:PackageDimensions>
            <ns2:Height Units="inches">3.07</ns2:Height>
            <ns2:Length Units="inches">8.90</ns2:Length>
            <ns2:Width Units="inches">6.06</ns2:Width>
            <ns2:Weight Units="pounds">0.55</ns2:Weight>
          </ns2:PackageDimensions>
          <ns2:PackageQuantity>1</ns2:PackageQuantity>
          <ns2:PartNumber>M06484</ns2:PartNumber>
          <ns2:ProductGroup>Hobby</ns2:ProductGroup>
          <ns2:ProductTypeName>TOYS_AND_GAMES</ns2:ProductTypeName>
          <ns2:Publisher>Max Factory</ns2:Publisher>
          <ns2:ReleaseDate>2017-10-31</ns2:ReleaseDate>
          <ns2:SmallImage>
            <ns2:URL>http://ecx.images-amazon.com/images/I/51geCQ766OL._SL75_.jpg</ns2:URL>
            <ns2:Height Units="pixels">75</ns2:Height>
            <ns2:Width Units="pixels">54</ns2:Width>
          </ns2:SmallImage>
          <ns2:Studio>Max Factory</ns2:Studio>
          <ns2:Title>figma キルラキル 纏流子 ノンスケール ABS&PVC製 塗装済み可動フィギュア 再販</ns2:Title>
        </ns2:ItemAttributes>
      </AttributeSets>
      <Relationships/>
      <SalesRankings>
        <SalesRank>
          <ProductCategoryId>hobby_display_on_website</ProductCategoryId>
          <Rank>18480</Rank>
        </SalesRank>
        <SalesRank>
          <ProductCategoryId>2189356051</ProductCategoryId>
          <Rank>2366</Rank>
        </SalesRank>
      </SalesRankings>
    </Product>
  </Products>
</GetMatchingProductForIdResult>
<GetMatchingProductForIdResult Id="4571368442307" IdType="EAN" status="Success">
  <Products xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
    <Product>
      <Identifiers>
        <MarketplaceASIN>
          <MarketplaceId>A1VC38T7YXB528</MarketplaceId>
          <ASIN>B00P0BQUYY</ASIN>
        </MarketplaceASIN>
      </Identifiers>
      <AttributeSets>
        <ns2:ItemAttributes xml:lang="ja-JP">
          <ns2:Binding>おもちゃ＆ホビー</ns2:Binding>
          <ns2:Brand>グッドスマイルカンパニー</ns2:Brand>
          <ns2:ItemDimensions>
            <ns2:Height Units="inches">3.00</ns2:Height>
            <ns2:Length Units="inches">8.00</ns2:Length>
            <ns2:Width Units="inches">4.00</ns2:Width>
            <ns2:Weight Units="pounds">1.28</ns2:Weight>
          </ns2:ItemDimensions>
          <ns2:IsAdultProduct>false</ns2:IsAdultProduct>
          <ns2:Label>グッドスマイルカンパニー</ns2:Label>
          <ns2:ListPrice>
            <ns2:Amount>10800.00</ns2:Amount>
            <ns2:CurrencyCode>JPY</ns2:CurrencyCode>
          </ns2:ListPrice>
          <ns2:Manufacturer>グッドスマイルカンパニー</ns2:Manufacturer>
          <ns2:ManufacturerMaximumAge Units="months">180.00</ns2:ManufacturerMaximumAge>
          <ns2:ManufacturerMinimumAge Units="months">168.00</ns2:ManufacturerMinimumAge>
          <ns2:Model>SEP148310</ns2:Model>
          <ns2:PackageDimensions>
            <ns2:Height Units="inches">6.54</ns2:Height>
            <ns2:Length Units="inches">10.79</ns2:Length>
            <ns2:Width Units="inches">7.87</ns2:Width>
            <ns2:Weight Units="pounds">1.28</ns2:Weight>
          </ns2:PackageDimensions>
          <ns2:PackageQuantity>1</ns2:PackageQuantity>
          <ns2:PartNumber>SEP148310</ns2:PartNumber>
          <ns2:ProductGroup>Hobby</ns2:ProductGroup>
          <ns2:ProductTypeName>TOYS_AND_GAMES</ns2:ProductTypeName>
          <ns2:Publisher>グッドスマイルカンパニー</ns2:Publisher>
          <ns2:ReleaseDate>2015-08-08</ns2:ReleaseDate>
          <ns2:Size>全高：約210mm</ns2:Size>
          <ns2:SmallImage>
            <ns2:URL>http://ecx.images-amazon.com/images/I/51H1EV5qzYL._SL75_.jpg</ns2:URL>
            <ns2:Height Units="pixels">75</ns2:Height>
            <ns2:Width Units="pixels">56</ns2:Width>
          </ns2:SmallImage>
          <ns2:Studio>グッドスマイルカンパニー</ns2:Studio>
          <ns2:Title>キルラキル 鬼龍院皐月 鮮血Ver. 1/8スケール ABS&ATBC-PVC製 塗装済み完成品フィギュア</ns2:Title>
        </ns2:ItemAttributes>
      </AttributeSets>
      <Relationships/>
      <SalesRankings>
        <SalesRank>
          <ProductCategoryId>hobby_display_on_website</ProductCategoryId>
          <Rank>77338</Rank>
        </SalesRank>
        <SalesRank>
          <ProductCategoryId>2189356051</ProductCategoryId>
          <Rank>10433</Rank>
        </SalesRank>
      </SalesRankings>
    </Product>
    <Product>
      <Identifiers>
        <MarketplaceASIN>
          <MarketplaceId>A1VC38T7YXB528</MarketplaceId>
          <ASIN>B0188100YI</ASIN>
        </MarketplaceASIN>
      </Identifiers>
      <AttributeSets>
        <ns2:ItemAttributes xml:lang="ja-JP">
          <ns2:Brand>グッドスマイルカンパニー</ns2:Brand>
          <ns2:IsAdultProduct>false</ns2:IsAdultProduct>
          <ns2:Label>Good Smile</ns2:Label>
          <ns2:Manufacturer>Good Smile</ns2:Manufacturer>
          <ns2:ProductGroup>Hobby</ns2:ProductGroup>
          <ns2:ProductTypeName>HOBBIES</ns2:ProductTypeName>
          <ns2:Publisher>Good Smile</ns2:Publisher>
          <ns2:SmallImage>
            <ns2:URL>http://ecx.images-amazon.com/images/I/51NjcNgP%2B3L._SL75_.jpg</ns2:URL>
            <ns2:Height Units="pixels">75</ns2:Height>
            <ns2:Width Units="pixels">56</ns2:Width>
          </ns2:SmallImage>
          <ns2:Studio>Good Smile</ns2:Studio>
          <ns2:Title>Good Smile Kill La Kill: Satsuki Kiryuin (Senketsu Version) PVC Figure [並行輸入品]</ns2:Title>
        </ns2:ItemAttributes>
      </AttributeSets>
      <Relationships/>
      <SalesRankings/>
    </Product>
  </Products>
</GetMatchingProductForIdResult>
<ResponseMetadata>
  <RequestId>0932d9f9-f34d-4307-8a59-79d3c3804825</RequestId>
</ResponseMetadata>
</GetMatchingProductForIdResponse>
```

## レスポンスの解析
レスポンスを掘って掘って解析していきます。
今回の例は単純に商品のタイトルを配列に格納するというロジックです。

```ruby
# 先ほどの続き
responce = client.get_matching_product_for_id(id_type, ids).xml
titles = []
results = response.dig('GetMatchingProductForIdResponse', 'GetMatchingProductForIdResult')
# [注意] 1商品だけ取得した場合eachで回す必要はないです。
results.each do |result|
  titles << result.dig('Products', 'Product', 'AttributeSets', 'ItemAttributes', 'Title')
end
```

結構上層部のタイトルでさえこれくらいは掘らないと取得できません。
共通化できる部分はうまく共通化して商品情報を取得するようにしましょう。

あとは煮るなり焼くなり...

# 注意点
- 商品のサイズ系の単位はインチ
- 商品の重さ系の単位はポンド