1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React Native Expo】書籍検索API比較してみた(Google Books・OpenBD・楽天ブックス・NDLサーチ)

1
Last updated at Posted at 2026-05-13

概要

書籍検索APIの選定に関する話です。iOSアプリ「ほんとも」では書籍検索に2つのAPIを使用しています。本記事ではどのような経緯で書籍検索APIを選定したのかを記事にしました。

登場する API 一覧

本記事で扱う API は全部で4つ。先に結論からお伝えすると、当初は使いやすさの観点からGoogle Books APIとOpenBDを選んでいましたが、途中で楽天ブックスとNDLサーチに乗り換えました。

採用したAPI

楽天ブックス API

ポイント 詳細
ISBN の一意管理 書籍情報(電子、文庫、ハードカバー)が1つに集約されており、検索結果に重複がない
和書カバー率 国内流通書籍に特化したデータベースのため、日本語書籍の収録漏れが少ない
取得件数 1リクエストあたり最大30件(Google Books の20件より多い)

※利用には楽天デベロッパーアカウントへの登録と Application ID・Access Key が必要

国立国会図書館サーチ(NDLサーチ)

ポイント 詳細
NDC ジャンル NDC(日本十進分類法)コードを提供しており、ジャンルフィルタ機能の実装に不可欠
ライセンス表記 商用利用には利用規約の確認とアプリ内表記が必要

見送ったAPI

Google Books API

問題点 詳細
書籍の重複 書籍が電子書籍版、文庫版、ハードカバー版それぞれ個別で存在する
和書カバー率の低さ 国内流通書籍の収録漏れが多い

OpenBD

問題点 詳細
ジャンル情報の欠如 NDC コードなどのジャンル分類情報を提供していない

著者名・出版社の補完精度は問題なかったが、ジャンル情報取得のために NDLサーチへの移行を決めました。

背景

当時、利用ハードルの低さから、書籍検索にGoogle Books APIOpenBDを使用しており、その中で以下の課題がありました。

【課題1】和書重複・カバー率

  • 書籍の重複表示: Google Books APIにおいて、電子版、文庫版、ハードカバー版など検索結果に同じ本が何冊も並ぶ。
  • 和書カバー率の低さ: 国内流通の一般的な書籍が検索にヒットしないケースがあった。

【課題2】書籍ジャンルが取得できない

  • 書籍登録時の情報補完(著者名・出版社)に OpenBD を使用していました。本棚のジャンルフィルタ機能を追加するにあたり、Google Books APIOpenBD はジャンル情報(NDC コード)を提供していないため、別の API への移行が必要になりました。

ゴール: ISBN が一意に管理され、和書の収録率が高い API に移行し、書籍ジャンルでのフィルタ機能を実現する。

どうやって解決したのか

利用時の注意点

まず、楽天ブックスAPIについて、こちらはRakuten DevelopersからアプリIDを発行し、アプリケーションIDとアクセスキーの2つを取得しておく必要があります。こちらは認証情報なので.envなどで管理した方が良いかと思います。

一方、NDLサーチAPIを用いた書籍検索は以下のAPI仕様を参考にしました。また、レスポンスのパース処理について一部設定が必要な箇所がありました。

NDLサーチAPIのレスポンスのパース処理

私の場合、NDLサーチは検索用APIとしてOpenSearchを利用しており、レスポンスは XML(RSS 2.0)形式でした。そこで、fast-xml-parser でパースしました。ここで、parseTagValue: false を忘れると NDC コードが崩れることに注意が必要です。例えば、NDC コードの "007.63"7.63(数値)に変換され、先頭ゼロが失われます。

import { XMLParser } from 'fast-xml-parser';

// ❌ デフォルト設定(parseTagValue が true)
const parser = new XMLParser({ ignoreAttributes: false });
// "007.63" → 7.63(数値)になり、先頭ゼロが消える

// ✅ parseTagValue: false で数値変換を無効化
const parser = new XMLParser({
  ignoreAttributes: false,
  parseTagValue: false,  // "007.63" を文字列のまま保持
});

【補足】NDCコード→ジャンル名へのマッピング

NDC Navi を参考にマッピングを作成しています。NDC→ジャンル名の変換処理を用意し、画面表示する際はNDC→ジャンル名変換します。参考までに下表とそれを用いたサンプルコードを共有します。

NDC ジャンル
0 総記
1 哲学・心理学
2 歴史・地理
3 社会科学
4 自然科学
5 技術・工学
6 産業
7 芸術・スポーツ
8 言語
9 文学
const NDC_MAP: Record<string, string> = {
  '0': '総記',
  '1': '哲学・心理学',
  '2': '歴史・地理',
  '3': '社会科学',
  '4': '自然科学',
  '5': '技術・工学',
  '6': '産業',
  '7': '芸術・スポーツ',
  '8': '言語',
  '9': '文学',
};

export function ndcToGenre(code: string): string {
  return NDC_MAP[code.charAt(0)] ?? 'その他';
}
【参考】書籍ジャンルの取得

感想

今回、国内向けに和書を幅広く取り扱える、かつ、書籍ジャンルを取得できるという観点から楽天ブックスAPINDLサーチAPIの2つを結果的に採用しました。また、Google Books APIでは電子版、文庫版などで同じ書籍データを取得できるため、重複削除のロジックが必要になることや、NDLサーチの実装では parseTagValue: false の見落としが典型的なハマりどころだったことなど、書籍検索のAPI選定で勉強になることが多くありました。

最後までお読みいただきありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?