📚

JavaScript で Google Books APIs 使って本を検索して結果一覧を表示するツールを作ってみた

2021/01/12に公開

はじめに

弊社のメンバーが, 社内開発イベントで本を検索するサービスを作ってみたいということだったので調査がてら Google Books APIs を触ってみました.

思いのほか簡単に使えたのでサンプルを交えて使い方を紹介しようと思います.

Google Books APIs とは?

Google Books APIs とは, 書籍検索 API のひとつで Google が提供しているサービスになります.
認証いらずで, インターフェースもシンプルなのでちょっとしたサービスの検証やプログラミング初学者への課題として使えます.

var res = await fetch('https://www.googleapis.com/books/v1/volumes?q=鬼滅');
var data = await res.json();

console.log(data); // "鬼滅" と付く本のデータが表示される

ただ, 出版社や価格といった情報は取得できないのでご注意を!

サンプルプログラム

今回作ったサンプルです.

https://runstant.com/phi/projects/10f05a88

フォームに値を入力すると検索結果が表示されます.

コード

index.html
  <body class='p16'>
    <h1 class='mb16'>${title}</h1>

    <input class='input bg-white mb16' type='search' id='$q' />
    
    <div>
      <h2 class='mb8'>検索結果</h2>
      <div id='$results'></div>
    </div>
    
    <script>${script}</script>
  </body>
main.js
window.onload = async function() {
  // 検索する
  var search = async () => {
    // 入力された値でを本を検索
    var items = await searchBooks($q.value);
    
    // html に変換して表示用 DOM に代入
    var texts = items.map(item => {
      return `
      <a class='f border bg-white mb8' href='${item.link}', target='_blank'>
        <img class='w100 object-fit-contain bg-gray' src='${item.image}' />
        <div class='p16'>
          <h3 class='mb8'>${item.title}</h3>
          <p class='line-clamp-2'>${item.description}</p>
        </div>
      </div>`;
    });
    $results.innerHTML = texts.join('');
  };
  
  // 入力するたびに検索( debounce で API 連打対策 )
  $q.oninput = _.debounce(search, 256);
  
  // フォーカスしたら全文字選択
  $q.onfocus = () => { $q.select(); };
  
  // 初期値設定
  $q.value = '鬼滅';
  search();
};

// 本を検索して結果を返す
var searchBooks = async (query) => {
  // Google Books APIs のエンドポイント
  var endpoint = 'https://www.googleapis.com/books/v1';
  
  // 検索 API を叩く
  var res = await fetch(`${endpoint}/volumes?q=${$q.value}`);
  // JSON に変換
  var data = await res.json();
  
  // 必要なものだけ抜き出してわかりやすいフォーマットに変更する
  var items = data.items.map(item => {
    var vi = item.volumeInfo;
    return {
      title: vi.title,
      description: vi.description,
      link: vi.infoLink,
      image: vi.imageLinks ? vi.imageLinks.smallThumbnail : '',
    }; 
  });
  
  return items;
};

解説

Google Books APIs を叩く

まずは, 本題である Google Books APIs を使っている箇所について解説します.

使い方はシンプルでエンドポイントである https://www.googleapis.com/books/v1volumes というパスをくっつけると
検索用の API のパスになります.

そこにクエリとして q=検索ワード を渡すとそのワードにヒットする本の一覧を返してくれます.

// Google Books APIs のエンドポイント
var endpoint = 'https://www.googleapis.com/books/v1';

// 検索 API を叩く
var res = await fetch(`${endpoint}/volumes?q=${$q.value}`);
// JSON に変換
var data = await res.json();

fetch 後に json に変換するのも忘れずに!!

Google Books APIs から返ってきたデータフォーマットを整形しよう

以下の処理では, Google Books APIs から返ってきたデータを使いやすいよう整形しています.

// 必要なものだけ抜き出してわかりやすいフォーマットに変更する
var items = data.items.map(item => {
  var vi = item.volumeInfo;
  return {
    title: vi.title,
    description: vi.description,
    link: vi.infoLink,
    image: vi.imageLinks ? vi.imageLinks.smallThumbnail : '',
  }; 
});

Google Books APIs は様々なパターンに対応するために多くのデータを返します.
ただ今回のように一覧を表示するだけといった場合ではちょっと上長です.

それを検索機能を使う側に意識させないために関数側でフォーマットを整形して返しています.

debounce を使って連続で API を実行しないよう対策しよう

今回のタイトルとはズレちゃうんですが, 検索でよく使わるテクニックについて紹介します.
以下のように underscore の debounce というメソッドで関数を包むことで一定間隔以下で呼ばれた場合の実行を間引いてくれます.

// 入力するたびに検索( debounce で API 連打対策 )
$q.oninput = _.debounce(search, 256);

Google Books APIs もそうですし一般的な API サービスもそうですが, 一定の条件を超えると API key が必要になったり課金が必要になったりするのでこういった対策もすごく大切だったりします!

フォーカスしたら全選択に!

以下のように focus 時に select 関数を読んであげることでフォームに入力した文字を全選択してくれます.

// フォーカスしたら全文字選択
$q.onfocus = () => { $q.select(); };

これもちょっとした tips ですが, 場面によっては UX 向上するのでおすすめです!

おわりに

今回は, Google Books APIs の使い方の一例を紹介しました.
世の中には便利な API がたくさんあるのでうまく活用することで色々なサービスを作ることができます.

難しいと思われがちですが, わりと簡単に使えたりします.
もちろん本格的にサービスに組み込むとなったら規約や料金プランについて調べる必要がありますが...

この記事をきっかけに, 外部データを使うといったハードルが少しでも下がって QOD(quality of development) が向上したら嬉しいです.

Reference

Google Books APIs のドキュメント

https://developers.google.com/books/docs/v1/using?hl=ja

Discussion