最近ネイティブアプリに興味が湧いてきたのでFlutterを触りはじめました。
今回はFlutterでAPIリクエストの実装例を紹介します。
基本的に以下のドキュメントを読めば実装できるのですが、複数件取得の場合の例がのってなかったので私同様、初心者の方に参考になればと思います。
https://flutter.dev/docs/cookbook/networking/fetch-data
対象のAPI
キャッシュレス店舗情報が取得できるAPIです。
https://api.cashless.go.jp/location/xn7/6uq.json
// エンコードされたデータ
{"13872":{"id":13872,"name":"\u30ab\u30e9\u30aa\u30b1\uff2f\uff2e\uff25\u9280\u5ea7\u5e97","addr":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a\u6709\u697d\u753a\uff11\u4e01\u76ee\uff12\uff0d\uff11\uff11\u3000\u30aa\u30fc\u30ad\u30c3\u30c9\u30b9\u30af\u30a8\u30a2\u30d3\u30eb\uff14\u3001\uff15\uff26","lat":35.6726177,"lng":139.7600767,"tel":"03-5510-1181","category":"115"},"29892":...
// デコードされたデータ
{13872: {id: 13872, name: カラオケONE銀座店, addr: 東京都千代田区有楽町1丁目2-11 オーキッドスクエアビル4、5F, lat: 35.6726177, lng: 139.7600767, tel: 03-5510-1181, category: 115}, 29892:...
モデルを作成
とりあえずlib/modelsにsotre.dartを作成しました。
lib/models/store.dart
class Store {
final String id;
final String name;
final int addr;
final double lat;
final double lng;
final String tel;
final String category;
Store({
this.id,
this.name,
this.addr,
this.lat,
this.lng,
this.tel,
this.category
});
factory Store.fromJson(Map<String, dynamic> json) {
return Store(
id: json['id'],
name: json['title'],
addr: json['title'],
lat: json['lat'],
lng: json['lng'],
tel: json['tel'],
category: json['category'],
);
}
}
Dartでよく使うBuilt-in typesです。(TypeScriptから頭を切り替える時に混乱するので自分用メモ)
タイプ | 表記 |
---|---|
数値 | int, double |
文字列 | String |
真偽 | bool |
配列 | List |
セット | Set |
Key/Value | Map |
JSONをデコード
main.dart
import 'package:json_annotation/json_annotation.dart';
import 'dart:convert' show json;
@JsonSerializable()
...
Future<List<Store>> fetchStores() async {
final response = await http.get('https://api.cashless.go.jp/location/xn7/6uq.json');
if (response.statusCode == 200) {
Map<String, dynamic> decodedJson = json.decode(response.body);
}
...
JSONをデコードするだけなのにimportするものが多いと感じましたが、こういうものなんでしょう。
モデルのリストを返す
デコードしたJSONの型がMap<String, dynamic>
なのでforEach
で回し、モデルのリストを生成して返しました。
main.dart
import 'dart:async';
import 'package:http/http.dart' as http;
import 'models/store.dart';
import 'package:json_annotation/json_annotation.dart';
import 'dart:convert' show json;
@JsonSerializable()
...
Future<List<Store>> fetchStores() async {
final response = await http.get('https://api.cashless.go.jp/location/xn7/6uq.json');
if (response.statusCode == 200) {
List<Store> stores = [];
print(response.body);
Map<String, dynamic> decodedJson = json.decode(response.body);
decodedJson.forEach((key, value) =>
stores.add(Store.fromJson(decodedJson[key]))
);
return stores;
} else {
throw Exception('Failed to load album');
}
}
期待通りの結果が返ってきてますね。
main.dart
_stores = await fetchStores();
print(_stores);
> [Instance of 'Store', Instance of 'Store', ...]
以上です。