FlutterでAPI呼び出し(GET/POST/DELETE)をしてみた

2024.02.13

こんにちは、ゲームソリューション部のsoraです。
今回は、FlutterでAPI呼び出し(GET/POST/DELETE)をしてみたことについて書いていきます。

実装した画面

GET・POST・DELETEボタンをそれぞれ押下すると、API呼び出しが実行されて受け取った情報を表示します。
DELETEのみレスポンスコードを返すようにしています。
使用しているパッケージは以下のhttpパッケージです。
http | Dart package

各Clearボタンでは、API呼び出しにより取得したデータの表示を削除しています。(内部的には空文字を上書きしているだけです。)

コードの解説

main.dart

こちらは新規プロジェクト作成時のコードからStatelessWidgetを抜き出して少し変えているだけなので、特に解説はしません。

main.dart

import 'package:flutter/material.dart';
import 'app.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Sample',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

app.dart

まずコードは以下です。

app.dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; // HTTPリクエスト用パッケージ
import 'dart:convert'; // JSONへの変換用パッケージ

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

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

class _MyHomePageState extends State<MyHomePage> {
  dynamic getResponseState = '';
  dynamic postResponseState = '';
  dynamic deleteResponseState;
  dynamic responseState;

  Future<void> getData() async {
    final response = await http.get(Uri.https('reqres.in', '/api/users/2'));
    final jsonResponse = jsonDecode(response.body);
    setState(() {
      getResponseState = jsonResponse;
    });
  }
  Future<void> postData() async {
    final response = await http.post(
        Uri.https('reqres.in', '/api/users'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(<String, String>{
          'name': "sora",
          'job': "engineer"
        })
    );
    final jsonResponse = jsonDecode(response.body);
    setState(() {
      postResponseState = jsonResponse;
    });
  }
  Future<void> deleteData() async {
    final response = await http.delete(Uri.https('reqres.in', '/api/users/2'));
    setState(() {
      deleteResponseState = response.statusCode;
    });
  }

  Future<void> getClearData() async {
    setState(() {
      getResponseState = '';
    });
  }
  Future<void> postClearData() async {
    setState(() {
      postResponseState = '';
    });
  }
  Future<void> deleteClearData() async {
    setState(() {
      deleteResponseState = '';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('API Test'),
      ),
      body: Center(
        child: Column(
          children: [
            Text(
              '$getResponseState',
              style: const TextStyle(fontSize: 15),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: getData,
                  child: const Text('GET'),
                ),
                ElevatedButton(
                  onPressed: getClearData,
                  child: const Text('Clear'),
                ),
              ],
            ),
            Text(
              '$postResponseState',
              style: const TextStyle(fontSize: 15),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: postData,
                  child: const Text('POST'),
                ),
                ElevatedButton(
                  onPressed: postClearData,
                  child: const Text('Clear'),
                ),
              ],
            ),
            Text(
              '$deleteResponseState',
              style: const TextStyle(fontSize: 15),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: deleteData,
                  child: const Text('DELETE'),
                ),
                ElevatedButton(
                  onPressed: deleteClearData,
                  child: const Text('Clear'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

httpパッケージを使用して、getData()postData()deleteData()でAPI呼び出しをして、取得した値をsetState()で設定しています。
GETメソッド(getData())では、Uri.https('{ドメイン}', '{パス}')で指定しています。
DELETEもgetの部分がdeleteになっていることと、レスポンスボディを入れているかステータスコードを入れているかだけの差分です。

Future<void> getData() async {
  final response = await http.get(Uri.https('reqres.in', '/api/users/2'));
  final jsonResponse = jsonDecode(response.body);
  setState(() {
    getResponseState = jsonResponse;
  });
}

POSTメソッド(postData())は、リクエストとしてヘッダーとボディをjson形式で入れてAPI呼び出しをしています。

Future<void> postData() async {
  final response = await http.post(
      Uri.https('reqres.in', '/api/users'),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode(<String, String>{
        'name': "sora",
        'job': "engineer"
      })
  );
  final jsonResponse = jsonDecode(response.body);
  setState(() {
    postResponseState = jsonResponse;
  });
}

値のClearについては、httpパッケージは関係ないですが、getClearData()postClearData()deleteClearData()で取得した値を空文字で上書きしています。

Future<void> getClearData() async {
  setState(() {
    getResponseState = '';
  });
}
Future<void> postClearData() async {
  setState(() {
    postResponseState = '';
  });
}
Future<void> deleteClearData() async {
  setState(() {
    deleteResponseState = '';
  });
}

最後に

今回は、FlutterでAPI呼び出し(GET/POST/DELETE)をしてみたことを記事にしました。
どなたかの参考になると幸いです。