FlutterでREST APIを叩いて取得したデータを表示してみた

2022.04.15

こんにちは、CX事業本部IoT事業部の高橋雄大です。

REST API(RESTful API)を利用してデータの取得と表示をやってみたいと思います。今回はまずAPIのリクエスト方法を学習したいので、例外処理やModelの実装はしていません。Flutterの公式ドキュメントに沿ったシンプルな方法で実装していきます。

本記事のゴール

Google Books APIを利用してブックリストを表示します。

Flutter REST API

環境情報

項目 内容
OS macOS Monterey 12.3 (21E230)
Visual Studio Code 1.66.0
Xcode 13.3 (13E113)
Flutter 2.10.4
Dart 2.16.2

ブックリストを実装

HTTPリクエストに必要なhttpパッケージをFlutterのプロジェクトへ追加します。

flutter pub add http

main.dartでブックリストを実装します。

lib/main.dart

import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Sample',
      home: MyHomePage(title: 'Flutter Sample'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List items = [];

  Future<void> getData() async {
    var response = await http.get(Uri.https(
        'www.googleapis.com',
        '/books/v1/volumes',
        {'q': '{Flutter}', 'maxResults': '40', 'langRestrict': 'ja'}));

    var jsonResponse = jsonDecode(response.body);

    setState(() {
      items = jsonResponse['items'];
    });
  }

  @override
  void initState() {
    super.initState();

    getData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Sample'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: Column(
              children: <Widget>[
                ListTile(
                  leading: Image.network(
                    items[index]['volumeInfo']['imageLinks']['thumbnail'],
                  ),
                  title: Text(items[index]['volumeInfo']['title']),
                  subtitle: Text(items[index]['volumeInfo']['publishedDate']),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

解説

Futureで非同期処理にして、StatefulWidgetsetStateでデータを更新&画面の再描写を実現しています。

lib/main.dart

class _MyHomePageState extends State<MyHomePage> {
  List items = [];

  Future<void> getData() async {
    var response = await http.get(Uri.https(
        'www.googleapis.com',
        '/books/v1/volumes',
        {'q': '{Flutter}', 'maxResults': '40', 'langRestrict': 'ja'}));

    var jsonResponse = jsonDecode(response.body);

    setState(() {
      items = jsonResponse['items'];
    });
  }

ListView.builderでリストを生成して、その中にCardを作成しています。カード内では取得した本の情報を出力しています。

lib/main.dart

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Sample'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: Column(
              children: <Widget>[
                ListTile(
                  leading: Image.network(
                    items[index]['volumeInfo']['imageLinks']['thumbnail'],
                  ),
                  title: Text(items[index]['volumeInfo']['title']),
                  subtitle: Text(items[index]['volumeInfo']['publishedDate']),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

動作確認

画像付きのブックリストが表示されることを確認できました。

Flutter REST API

まとめ

HTTPリクエスト自体はとても簡単に実装することができました。画面の描写について、取得したデータを変数へ直接代入すると再描写がされませんでした。画面を再描写するにはStatefulWidgetsetStateで状態を更新しなければならないので、慣れていない場合には注意が必要です。

参考資料