FlutterでHTTPリクエストを使用する方法
序章
アプリケーションは、POSTおよびGETおよびその他のHTTP要求を頻繁に実行する必要があります。
Flutterは、HTTPリクエストの作成をサポートするhttpパッケージを提供します。
この記事では、httpパッケージを使用してHTTPリクエストを実行してプレースホルダー情報を表示するFlutterアプリの例を作成します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Flutterをダウンロードしてインストールします。
- Android StudioまたはVisual StudioCodeをダウンロードしてインストールするには。
- コードエディタ用のプラグインをインストールすることをお勧めします。 AndroidStudio用にインストールされたFlutterおよびDartプラグイン。 VisualStudioCode用にインストールされたFlutter拡張機能。
このチュートリアルは、Flutter v1.22.2、Android SDK v30.0.2、およびAndroidStudiov4.1で検証されました。
ステップ1—プロジェクトの設定
セットアップを実行するために、Flutterアプリの例を作成します。
Flutter用に環境を設定したら、次のコマンドを実行して新しいアプリケーションを作成できます。
flutter create flutter_http_example
新しいプロジェクトディレクトリに移動します。
cd flutter_http_example
flutter createを使用すると、ボタンがクリックされた回数を表示するデモアプリケーションが作成されます。
コードエディタでpubspec.yamlを開き、次のプラグインを追加します。
pubspec.yaml
dependencies:
flutter:
sdk: flutter
http: ^0.12.0+2
これはdart.devによって公開された公式のFlutterプラグインであり、 100 % he althスコアを持っているため、このプラグインの信頼性を信頼できます。
ステップ2—GETリクエストの処理
最初のタスクは、APIとの対話に使用できるクラスを作成することです。
コードエディタを開き、libディレクトリにhttp_service.dartファイルを作成します。 ここでは、新しいHttpServiceクラスを開発し、getPosts関数を追加します。
lib / http_service.dart
import 'dart:convert';
import 'package:http/http.dart';
import 'post_model.dart';
class HttpService {
final String postsURL = "https://jsonplaceholder.typicode.com/posts";
Future<List<Post>> getPosts() async {
Response res = await get(postsURL);
if (res.statusCode == 200) {
List<dynamic> body = jsonDecode(res.body);
List<Post> posts = body
.map(
(dynamic item) => Post.fromJson(item),
)
.toList();
return posts;
} else {
throw "Unable to retrieve posts.";
}
}
}
この例では、JSONプレースホルダーに接続します。 このコードは、postsURL文字列でhttpパッケージのgetを使用します。
そのリクエストが成功した場合、このコードはPost.fromJsonを使用してList<Post>を返します。 それ以外の場合は、エラーメッセージがスローされます。
ノート: HTTPステータスコード are used to determine if a request was successful or unsuccessful. A status code of 200 represents a successful HTTP request.
次に、コードエディタを使用して、libディレクトリにpost_model.dartファイルを作成します。 ここでは、新しいPostクラスを開発します。
lib / post_model.dart
import 'package:flutter/foundation.dart';
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({
@required this.userId,
@required this.id,
@required this.title,
@required this.body,
});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'] as int,
id: json['id'] as int,
title: json['title'] as String,
body: json['body'] as String,
);
}
}
JSONプレースホルダーからの応答をシリアル化するために、このコードは、JSONMapに基づくfromJsonメソッドを使用して新しいPostを返します。
注:本番アプリケーションでは、 json_serializable のようなパッケージを使用して、シリアル化を自動的に処理できます。
JSONプレースホルダーによって返されるPostは、userId、id、title、およびbodyで構成されます。
手順3—Postsを表示する
次に、コードエディタを使用して、libディレクトリにposts.dartファイルを作成します。 ここでは、HTTPリクエストからJSONプレースホルダーに返されるPostsを表示するPostsPageクラスを作成します。
lib / posts.dart
import 'package:flutter/material.dart';
import 'http_service.dart';
import 'post_model.dart';
class PostsPage extends StatelessWidget {
final HttpService httpService = HttpService();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Posts"),
),
body: FutureBuilder(
future: httpService.getPosts(),
builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.hasData) {
List<Post> posts = snapshot.data;
return ListView(
children: posts
.map(
(Post post) => ListTile(
title: Text(post.title),
subtitle: Text("${post.userId}"),
),
)
.toList(),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
このコードは、FutureBuilderウィジェットを使用して、getPosts()関数と対話します。 これにより、コードはList<Post>の準備ができたことを判断し、それに応じて動作することができます。
snapshot.hasDataがfalseの場合、CircularProgressIndicatorが表示されます。 それ以外の場合は、投稿情報付きのListTileが表示されます。
これまでの内容を確認するには、main.dartのコードを置き換える必要があります。
コードエディタでlib/main.dartを開き、PostsPageを使用するように変更します。
lib / main.dart
import 'package:flutter/material.dart';
import 'posts.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'HTTP',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: PostsPage(),
);
}
}
コードをコンパイルして、エミュレーターで実行します。
JSONプレースホルダーによって返される投稿のタイトルとユーザーIDのリストを確認する必要があります。
注:タイトルは、プレースホルダーテキストとして頻繁に使用される LoremIpsumからの抜粋です。
次のステップは、ユーザーが投稿のタイトルをクリックしたときに、投稿に関する詳細情報を含む詳細ページを作成することです。
手順4—PostDetailを表示する
ユーザーが投稿をタップした場合、アプリはユーザーをPostDetailページに移動する必要があります。
コードエディタを使用して、libディレクトリにpost_detail.dartファイルを作成します。 ここでは、個々のPostを表示するPostDetailクラスを作成します。
lib / post_detail.dart
import 'package:flutter/material.dart';
import 'post_model.dart';
class PostDetail extends StatelessWidget {
final Post post;
PostDetail({@required this.post});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(post.title),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: <Widget>[
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ListTile(
title: Text("Title"),
subtitle: Text(post.title),
),
ListTile(
title: Text("ID"),
subtitle: Text("${post.id}"),
),
ListTile(
title: Text("Body"),
subtitle: Text(post.body),
),
ListTile(
title: Text("User ID"),
subtitle: Text("${post.userId}"),
),
],
),
),
],
),
),
)
);
}
}
このコードは、title、id、body、およびuserIdを表示します。
これまでの状況を確認するには、posts.dartを変更してpost_detail.dartをサポートする必要があります。
lib / posts.dart
import 'package:flutter/material.dart';
import 'http_service.dart';
import 'post_detail.dart';
import 'post_model.dart';
class PostsPage extends StatelessWidget {
final HttpService httpService = HttpService();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Posts"),
),
body: FutureBuilder(
future: httpService.getPosts(),
builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.hasData) {
List<Post> posts = snapshot.data;
return ListView(
children: posts
.map(
(Post post) => ListTile(
title: Text(post.title),
subtitle: Text("${post.userId}"),
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PostDetail(
post: post,
),
),
),
),
)
.toList(),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
コードをコンパイルして、エミュレーターで実行します。
次のステップは、投稿を削除して削除する機能を追加することです。
ステップ5—DELETEリクエストの処理
HTTPリクエストのもう1つの例は、DELETEメソッドの使用です。
コードエディタでhttp_service.dartに戻り、deletePost(int id)メソッドを作成します。
lib / http_service.dart
import 'dart:convert';
import 'package:http/http.dart';
import 'post_model.dart';
class HttpService {
final String postsURL = "https://jsonplaceholder.typicode.com/posts";
// ...
Future<void> deletePost(int id) async {
Response res = await delete("$postsURL/$id");
if (res.statusCode == 200) {
print("DELETED");
} else {
throw "Unable to delete post.";
}
}
}
コードエディタでpost_detail.dartに戻り、IconButtonをAppBar内のactions配列に追加します。 アイコンを押すと、関連する投稿が削除されます。
lib / post_detail.dart
import 'package:flutter/material.dart';
import 'http_service.dart';
import 'post_model.dart';
class PostDetail extends StatelessWidget {
final HttpService httpService = HttpService();
final Post post;
PostDetail({@required this.post});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(post.title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: () async {
await httpService.deletePost(post.id);
Navigator.of(context).pop();
},
)
],
),
// ...
);
}
}
コードをコンパイルして、エミュレーターで実行します。
投稿の詳細ページにアクセスすると、AppBarに削除アイコンボタンが表示されます。 ボタンを押すと、コンソールにメッセージが出力されます。
Outputflutter: DELETED
これは削除リクエストを表します。 JSONプレースホルダーとこのサンプルアプリケーションの制限により、投稿は実際には削除されません。
結論
この記事では、Flutterhttpパッケージを操作する方法を学びました。 これにより、投稿のリストをGETし、個々の投稿をDELETEすることができました。
post、put、patchなどの同様の操作も使用できます。 詳細については、公式ドキュメントを参照してください。