📖

【Flutter】Google Books APIで本を検索しよう!

に公開

Google BooksAPIっていうのを今日知ったのでアプリを一つ作ってみました。
これ面白いのがGCPの登録とがが不要でAPIkeyが公開されている所でしょう。

API key
https://www.googleapis.com/books/v1/volumes?q=Flutter

これでFlutterというタイトルが含まれた本をGoogle PlayBooksの中から10件取得できるという物です。

APIの仕様

APIの仕様は簡単です。itemの中に情報が入っているのでitemsの中を見ていきます。
今回作るのに必要なkeyを取り出します。
titleは本のタイトル、authorsは著者、descriptionは本の内容についてで本の表紙はimageLinksのリストの中でsmallThumbnailthumbnailです。
smallThumbnailの方が低解像度です。
あとはsaleInfokeyない購入リンクのbuyLinkと価格情報のlistPriceにあるamountです。

実装

まずはBooksクラスを定義して必要な情報をreturnできるようにします。

books.dart
class Books {
  final String title;
  final String authors;
  final String thumbnail;
  final String description;
  final String buyLink;
  final String amount;

  Books({
    required this.title,
    required this.authors,
    required this.thumbnail,
    required this.description,
    required this.buyLink,
    required this.amount,
  });
}

このBooksクラスを使ってreturnしてフロントで扱いやすいような関数を作成します。
jsonをMap<String,dynamic>に変換してdartで扱いやすい状態にしたあとreturnする時に.toListでListに変換することでフロントではListView.builderで扱います。

api.dart
import 'dart:convert';
import 'dart:io';
import 'books.dart';

Future<List<Books>> fetchBooks(String searchQuery) async {
  final api = HttpClient();
  final request = await api.getUrl(Uri.parse(
      'https://www.googleapis.com/books/v1/volumes?q=$searchQuery&maxResults=40'));
  final response = await request.close();

  final responseBody = await response.transform(const Utf8Decoder()).join();
  final Map<String, dynamic> jsonData = json.decode(responseBody);
  final List<dynamic> items = jsonData['items'] ?? [];

  // items から Books インスタンスを生成して返す
  return items.map((item) {
    final volumeInfo = item['volumeInfo'] ?? {};
    final saleInfo = item['saleInfo'] ?? {};
    return Books(
      title: volumeInfo['title'] ?? '',
      authors: (volumeInfo['authors'] ?? []).join(', '),
      thumbnail: (volumeInfo['imageLinks']?['thumbnail'] ?? ''),
      description: (volumeInfo['description'] ?? ''),
      buyLink: (saleInfo['buyLink'] ?? ''),
      amount: (saleInfo['listPrice']?['amount']?.toString() ?? '0'),
    );
  }).toList();
}

引数のsearchQueryは検索したい著書のタイトルでflutterやポケモンなどが入ってくる想定です。また&maxResults=40で上位40件の結果を取得しています。GPTに聞いたところBooksAPIの取得できる最大数だそうです。
フロントのコードは省きますが完成したのが以下のアプリです。

まとめ

このAPI楽しいですね。
厳密には、Google Books API は「APIキーなしでも使えるエンドポイントが存在する」仕様で一部の機能にはAPIキーが必要になりますが、書籍検索のような読み取り専用のアクセスはAPIキーなしでも利用可能となっています。
完全無料でここまで取得できるのは面白いと思います。今回は諸事情でfreezedを使えなかったのですがこれをfreezedで実装すればもっと楽にできると思います。
ちょっとした書籍検索アプリのプロトタイプや、教育系・読書記録系アプリでもすぐ使えそうです。

ぽちぽちのつどい

Discussion