やりたいこと
- アプリからPOSTでAPIを呼び出す。
- POSTパラメータをJSONで渡して、API側で受け取ってサーバに保存する。
- APIからのレスポンスメッセージをページに表示する。
上記「api success. This message from API.」は、APIからレスポンスしている文字列である。
前提
APIは任意の環境で作成済とする。
ここでは、PHPで自作したAPIを、下記URLでアクセスできるようにしてある(ローカルでのみ稼働。ネットには公開していない)。
http://172.16.0.223/creator/api/flutter_post_test
これをPOSTで呼び出す。API側では、渡されたパラメータをサーバのログに吐き出すようにしてあるので、
パラメータが確実に渡ったことをログで確認する。
IPアドレスは、自PCに起動したVirtualBox(仮想サーバ)のアドレスである。
APIのソース
今回はCakePHP3で実装した。id, name を受け取る。
public function flutterPostTestApi()
{
$id = $this->request->getData('id') ?? null;
$name = $this->request->getData('name') ?? null;
if (empty($id)) {
$this->badRequest('id is empty. This message from API.');
}
$response = [];
$response['id'] = $id;
$response['message'] = 'api success. This message from API.';
$this->httpNormalResponse($response);
}
[flutter] httpの許可
を参照。
[flutter] main.dart に リクエスト用のデータクラスを実装する。
下記クラスをnewする際に、
idとname(例えば、会員ID(数値)と会員名(文字列)を登録するようなAPIを想定)を、
コンストラクタで受け取ってメンバ変数に保持する。
class SampleRequest {
final int id;
final String name;
SampleRequest({
this.id,
this.name,
});
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
};
}
[flutter] main.dart に APIを呼び出す処理を実装する。
APIに渡すパラメータは
id: 1234
name: 大和賢一郎
とした。
APIからは message が文字列で返ってくるので、
それを画面に表示させる処理も含める。
Future<ApiResults> fetchApiResults() async {
var url = "http://172.16.0.223/creator/api/flutter_post_test";
var request = new SampleRequest(id: 1234, name: '大和賢一郎');
final response = await http.post(url,
body: json.encode(request.toJson()),
headers: {"Content-Type": "application/json"});
if (response.statusCode == 200) {
return ApiResults.fromJson(json.decode(response.body));
} else {
throw Exception('Failed');
}
}
[flutter] main.dart に APIからのレスポンスを受け取るデータクラスを実装する。
APIレスポンスの仕様に合わせて、受け取る変数を実装する。
今回は message を返すように実装した。
class ApiResults {
final String message;
ApiResults({
this.message,
});
factory ApiResults.fromJson(Map<String, dynamic> json) {
return ApiResults(
message: json['message'],
);
}
}
[flutter] main.dart に画面表示などを実装する。
class _MyAppState extends State<MyApp> {
Future<ApiResults> res;
@override
void initState() {
super.initState();
res = fetchApiResults();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'APIをPOSTで呼び出しJSONパラメータを渡す',
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: Scaffold(
appBar: AppBar(
title: Text('Api JSON Post Sample'),
),
body: Center(
child: FutureBuilder<ApiResults>(
future: res,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
snapshot.data.message.toString()
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
),
);
}
}
完成形 main.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<ApiResults> res;
@override
void initState() {
super.initState();
res = fetchApiResults();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'APIをPOSTで呼び出しJSONパラメータを渡す',
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: Scaffold(
appBar: AppBar(
title: Text('Api JSON Post Sample'),
),
body: Center(
child: FutureBuilder<ApiResults>(
future: res,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
snapshot.data.message.toString()
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
),
);
}
}
class ApiResults {
final String message;
ApiResults({
this.message,
});
factory ApiResults.fromJson(Map<String, dynamic> json) {
return ApiResults(
message: json['message'],
);
}
}
Future<ApiResults> fetchApiResults() async {
var url = "http://172.16.0.223/creator/api/flutter_post_test";
var request = new SampleRequest(id: 1234, name: '大和賢一郎');
final response = await http.post(url,
body: json.encode(request.toJson()),
headers: {"Content-Type": "application/json"});
if (response.statusCode == 200) {
return ApiResults.fromJson(json.decode(response.body));
} else {
throw Exception('Failed');
}
}
class SampleRequest {
final int id;
final String name;
SampleRequest({
this.id,
this.name,
});
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
};
}