(2021/12/12追記)以下の記事の情報は古いです。Freezedを使用しましょう。
はじめに
FlutterでJSONデータのHTTP通信をする方法に関しては[公式のドキュメント] (https://flutter.io/docs/cookbook/networking/fetch-data)で基本的な説明があります。
しかし、JSONをリクエストパラメータとしてPOSTする部分の記載が無かったので、そこを簡単に説明をしようと思います。
コード
モデルクラスをJSON化してencodeしたものをbodyで渡します。
あとはヘッダーのContent-Typeをapplication/jsonにする事を忘れずに。
class SampleRequest {
final String key;
final int order;
SampleRequest({
this.key,
this.order
});
Map<String, dynamic> toJson() => {
'key': key,
'order': order,
};
}
class SampleResponse {
final number sampleId;
final String sampleName;
SampleResponse({
this.sampleId,
this.sampleName
});
factory SampleResponse.fromJson(Map<String, dynamic> json) {
return Spot(
sampleId: json['sampleId'],
sampleName: json['sampleName'],
);
}
}
Future<SampleResponse> _requestSample() async {
var url = "http://example.com/sample"
var request = new SampleRequest(key: "key", order: 0);
final response = await http.post(url,
body: json.encode(request.toJson()),
headers: {"Content-Type": "application/json"});
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON
return SampleResponse.fromJson(json.decode(response.body));
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
}
といった感じのコードになります。
さいごに
つい先日、Flutter製のアプリを無事リリースする事ができました。
知り合いが開発するKoretteというWebサービスのアプリ版です。
ダウンロードはこちらから。観光地や地域にスポットを当てたクイズアプリです。ぜひ遊んでみてください!
おまけ
HTTP通信のモデルクラスを各API毎にゴリゴリ描いてたら、パラメータの多い時にとんでもなく大変でした。
例えばパラメータが10個あればコンストラクタやtoJsonやfromJsonで40行と中々の量に...
class Spot {
final num id;
final String spotName;
final String spotDescription;
final String adress;
final num latitude;
final num longitude;
final num townId;
final String townName;
final num prefectureId;
final String prefectureName;
Spot({
this.id,
this.spotName,
this.spotDescription,
this.adress,
this.latitude,
this.longitude,
this.townId,
this.townName,
this.prefectureId,
this.prefectureName,
});
factory Spot.fromJson(Map<String, dynamic> json) {
return Spot(
id: json['id'],
spotName: json['spotName'],
spotDescription: json['spotDescription'],
adress: json['adress'],
latitude: json['latitude'],
longitude: json['longitude'],
townId: json['townId'],
townName: json['townName'],
prefectureId: json['prefectureId'],
prefectureName: json['prefectureName'],
);
}
Map<String, dynamic> toJson() => {
'id': id,
'spotName': spotName,
'spotDescription': spotDescription,
'adress': adress,
'latitude': latitude,
'longitude': longitude,
'townId': townId,
'townName': townName,
'prefectureId': prefectureId,
'prefectureName': prefectureName,
};
}
この地味に苦しい繰り返し作業はrubyでコンバータを適当に作って解決しました。
converter.rb
これを使用すると、
class Spot {
final num id;
final String spotName;
final String spotDescription;
final String adress;
final num latitude;
final num longitude;
final num townId;
final String townName;
final num prefectureId;
final String prefectureName;
}
とだけ書いて、
ruby coverter.rb spot.dart
というコマンドを叩けば、上記のコンストラクタやtoJsonやfromJsonが含まれたdartファイルが生成されます。
無駄な改行とかあると動かないかもしれないので注意してください。
そんなこんなで自動化してたわけですが、後から調べたらjson_annotationというpackageがあって、それを使用すれば十分かもしれません。