【Flutter/Dart】httpパッケージでAPI通信を実装する方法!

この記事からわかること
- Flutter/DartでAPI通信を実装する方法
- httpパッケージ使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Meerkat
- Xcode:16.0
- Flutter:3.29.2
- Dart:3.7.2
- http:1.4.0
- Mac M1:Sequoia 15.4
FlutterでHTTP API通信を実装する
アプリケーションにおいてHTTP通信を使ったデータのやり取りは非常によく使われる機能の1つです。FlutterでREST APIなどを使用してクラウドからデータを取得したり、データを送信したり行うためにhttp
やdio
というパッケージが活用できます。
http
はシンプルで使いやすい反面、機能も制限されているので複雑なロジックは構築しずらいです。dio
は少し学習コストが高いですが、機能が豊富でリッチな実装を行うことが可能です。
httpパッケージ
http
はHTTP通信を行うための機能がまとまったHTTPクライアントパッケージです。GETやPOSTなどの標準的なHTTPメソッドに対応しており、headerやbodyのカスタマイズ、タイムアウト、async/awaitにも対応しています。
http
パッケージをまずは導入しておきます。
$ flutter pub add http
これでimport
文を追加することでhttp
パッケージの機能が使えるようになります。
import 'package:http/http.dart' as http;
使い方
http
ではHTTPメソッドに倣った処理がそのままの名称でメソッドとして定義されています。そのため直感的に使いやすく、シンプルな実装が行えるのがメリットになります。
- http.get()・・・データ取得
- http.post()・・・データ送信
- http.put()・・・データ置き換え
- http.patch()・・・データ一部更新
- http.delete()・・・データ削除
データ取得:GET
例えばデータ取得(GET)を例に実装方法を見てみます。引数にUri
型でエンドポイントとなるURLを指定するだけです。await
で同期的に実装することができ、結果はhttp.Response
型で取得することが可能です。
Future<void> fetchData({int page = 1, int perPage = 10}) async {
// Uri型でエンドポイントを構築
final url = Uri.parse('https://qiita.com/api/v2/items?page=$page&per_page=$perPage');
// API通信を実行
final response = await http.get(url);
if (response.statusCode == 200) {
print('成功: ${response.body}');
} else {
print('失敗: ${response.statusCode}');
}
}
jsonの変換はサポート対象外
http
ではhttp.Response
で受け取ったデータ(JSON)をマッピングする機能は用意されていません。そのためimport 'dart:convert';
を追加してjsonDecode
メソッドで変換します。
if (response.statusCode == 200) {
print('成功: ${response.body}');
final List<dynamic> jsonList = jsonDecode(response.body);
return jsonList.map((e) => QiitaItem.fromJson(e)).toList();
} else {
print('失敗: ${response.statusCode}');
}
jsonDecode
メソッドはJSONの中身によって返却されるデータ型が変わります。{...}
ならMap<String, dynamic>
、[{...}, {...}]
ならList<dynamic>
になります。
タイムアウト
ネットワークが不安定などで通信に時間がかかる場合に一定の時間でタイムアウトを設けて処理を停止させたい場合はtimeout
メソッドを使用します。タイムアウトが発生するとTimeoutException
がスローされます。
Future<void> fetchData() async {
// 200ステータスで7秒かかるAPI
final url = Uri.parse('https://httpstat.us/200?sleep=7000');
try {
final response = await http
.get(url);
.timeout(Duration(seconds: 2)); // 2秒でタイムアウトする
print('成功: ${response.body}');
} on TimeoutException catch (e) {
print('タイムアウトしました: $e');
} catch (e) {
print('その他のエラー: $e');
}
}
ヘッダーの追加
HTTPのヘッダーに認証情報などを持たせたい場合は引数headers
にJSON形式で内容を渡します。
final response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'title': 'テスト投稿',
'body': '本文',
'userId': 1,
}),
);
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。