API
fetchを使って楽天商品検索APIから商品情報を取得する
アプリ登録してIDを取得
前回の記事で紹介しているので割愛しますが、まだアプリ登録をしていない方は、以下の記事を参考にしてください。
テストフォームで確認
Rakuten Webserviceにアクセスすると、テストフォームでAPIのリクエストやレスポンスを確認できるので、まずはそれを使って進めていきます。
アプリ登録をしてテストフォームへ進むと、APIのリクエストに必要なIDなどのパラメーターが入った状態でテストできるので、そのまま実装に移りやすいです。
テストフォームは、上の画像のようになっており、フォームに必要な値を入力すると、リクエストURLが自動的に生成されます。
アプリ名
登録したアプリ名を入力します。
APIカテゴリー・API名・APIドメイン
今回は、カテゴリーを楽天市場系API、API名は楽天商品検索APIに設定します。
APIドメインは、触れないのでそのままでOKです。
返却方式
場合によってtext、xml形式などのケースもあるかと思いますが、今回はjsonです。
アプリID
登録したアプリのIDを入力します。
パラメータ
取得したい商品情報のキーワードや商品コード、店舗コードをして絞り込みができます。
様々なパラメータを設定できるので、ドキュメントを見て確認してみてください。
例えば、店舗コードを入力して特定の店舗の商品情報を取得することで、トップページの商品一覧などの更新を効率化できたりします。
URL
フォームに入力された内容をリクエストするためのURLが自動的 に生成されます。
ここまでの状態でGETをクリックすると、レスポンスがjson形式で下部に表示されます。
実装サンプル
JavaScriptのfetchという機能を使った実装方法です。
パラメータやAPI名が変わっても、仕組みは同じなので、参考になると幸いです。
リクエスト用のURL確認
今回は、検索キーワードに私の大好きな「玉置浩二」を入れた検索結果をリクエストし、取得した情報を表示するサンプルになっています。
テストフォームでパラメータにkeyword = 玉置浩二を入力して、URLを確認しておきます。
また、サンプルでは、page = 1もパラメータに追加して、検索結果の1ページ目だけを取得するように指定しています。
アプリ名やアプリIDは、アプリ登録時に発行されたものを入れてください。
ちなみに、以下がテストフォームで返ってきたレスポンスの冒頭部分です。
{
"GenreInformation": [],
"Items": [
{
"Item": {
"affiliateRate": 2,
"affiliateUrl": "",
"asurakuArea": "群馬県/埼玉県/千葉県/東京都/神奈川県/新潟県/山梨県/長野県/岐阜県/静岡県/愛知県/三重県/滋賀県/宮城県/福島県/茨城県/栃木県",
"asurakuClosingTime": "12:00",
"asurakuFlag": 1,
"availability": 1,
"catchcopy": "【楽天ブックスならいつでも送料無料】",
"creditCardFlag": 1,
"endTime": "",
"genreId": "505042",
"giftFlag": 0,
"imageFlag": 1,
"itemCaption": "玉置浩二ビルボード クラシックス プレミアム シンフォニック コンサート 2021 ザ ユーラシアン ルネッサンス カペーリ ライブ タマキコウジ 発売日:2021年12月08日 予約締切日:2021年12月04日 日本コロムビア(株) COXAー1284 JAN:2100012781619 BILLBOARD CLASSICS PREMIUM SYMPHONIC CONCERT 2021[THE EURASIAN RENAISSANCE `KAPEL`] LIVE DVD ブルーレイ ミュージック・ライブ映像 A4クリアファイル",
"itemCode": "book:20500817",
"itemName": "【楽天ブックス限定先着特典】billboard classics PREMIUM SYMPHONIC CONCERT 2021『THE EURASIAN RENAISSANCE “КАПЕЛЬ”(カペーリ)』LIVE【Blu-ray】(A4クリアファイル) [ 玉置浩二 ]",
"itemPrice": 7920,
"itemUrl": "https://item.rakuten.co.jp/book/16923735/",
"mediumImageUrls": [
{
"imageUrl": "https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/1619/2100012781619_1_2.jpg?_ex=128x128"
}
],
"pointRate": 1,
"pointRateEndTime": "",
"pointRateStartTime": "",
"postageFlag": 0,
"reviewAverage": 5,
"reviewCount": 1,
"shipOverseasArea": "",
"shipOverseasFlag": 0,
"shopAffiliateUrl": "",
"shopCode": "book",
"shopName": "楽天ブックス",
"shopOfTheYearFlag": 0,
"shopUrl": "https://www.rakuten.co.jp/book/",
"smallImageUrls": [
{
"imageUrl": "https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/1619/2100012781619_1_2.jpg?_ex=64x64"
}
],
"startTime": "",
"tagIds": [
1011603
],
"taxFlag": 0
}
},
/*
.
.
Items配列に商品の数だけオブジェクトが格納されて返ってきます。
.
.
*/
],
}
テストフォームで行ったようなことを実際にコードを書いて実装していきます。
HTML
適当にcssも書いて整えておきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>玉置浩二の検索結果</title>
<style>
* {
box-sizing: border-box;
}
body,
div {
display: block;
max-width: 100%;
width: 100%;
margin: 0;
padding: 0;
font-size: 100%;
color: #333;
}
section {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
}
.items {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto;
gap: 30px 15px;
}
.items__link {
display: block;
color: inherit;
text-decoration: none;
cursor: pointer;
}
.items__image {
display: block;
width: 100%;
}
.items__name {
font-size: 12px;
}
.items__price {
font-weight: bold;
color: red;
}
</style>
</head>
<body>
<section>
<h1>玉置浩二の検索結果</h1>
<div class="items" id="js-allItem"></div>
</section>
<script src="./scripts.js"></script>
</body>
</html>
<div class="items" id="js-allItem"></div>
取得した商品情報を表示するコンテナ要素にidを付けておきます。
JavaScript
// scripts.js
(async () => {
const url = "テストフォームで表示されたURL";
const res = await fetch(url);
let json;
try {
if (res.ok) {
json = await res.json();
let allItem = "";
for (let i = 0; i < json.Items.length; i++) {
const product = json.Items[i].Item;
const productLink = product.itemUrl;
const productImage = product.mediumImageUrls[0].imageUrl;
const productName = product.itemName;
const productPrice = product.itemPrice.toLocaleString();
let allItemParts =
`<a href="` +
productLink +
`" target="_parent" class="items__link items__link--` +
(i + 1) +
`">
<img src="` +
productImage +
`" alt="` +
productName +
`" class="items__image">
<h2 class="items__name">` +
productName +
`</h2>
<p class="items__price">` +
productPrice +
`円</p>
</a>`;
allItem += allItemParts;
}
document.getElementById("js-allItem").innerHTML = allItem;
} else {
throw new Error(res.status);
}
} catch (e) {
console.error(e);
}
})();
const url = "テストフォームで表示されたURL";
テストフォームで確認できるリクエスト用のURLを入れてブラウザでhtmlを確認すると、以下の画像のようになっていると思います。
サンプルでは、非同期関数の中でfetchを使って取得した情報をfor文で商品の数だけ生成しているだけです。
非同期関数?
//非同期関数の基本構文
async function name([param[, param[, ...param]]]) {
statements
}
参照の解説を 引用すると、asyncとawaitというキーワードを使うことで、ダラダラした記述になりがちなプロミスベースの非同期処理を見通し良く書けます・・という感じです。
非同期と合わせて、Promise(プロミス)というワードも聞きなじみがあるのではないでしょうか。
今回のようにAPIを使って何かする際にはよく使うのですが、非同期処理に関しては、長くなるので別の機会に詳しく紹介できたらと思います。(変なこと書きそうなんで勉強し直します。)