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
などの同様の操作も使用できます。 詳細については、公式ドキュメントを参照してください。