Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート2
このチュートリアルシリーズのパート2へようこそ。最初のパートでは、Upstash、Serverless Framework、およびRedisを使用してRESTAPIを構築する方法を説明しました。
このパートでは、Flutterを使用してモバイルアプリケーションを構築し、RESTAPIエンドポイントを使用します。
始めましょう🙃
まず、フラッターをコンピューターにインストールして実行する必要があります
- フラッター
IDEで新しいフラッタープロジェクトを作成し、任意の名前を付けます。
pubspec.yaml
を開きます flutterプロジェクトのルートディレクトリにあるファイルを作成し、これらの依存関係をdev_dependencies
の下に追加します
timeago: ^3.1.0
shared_preferences: ^2.0.6
http: ^0.13.4
したがって、最終的には次のようになります
dev_dependencies:
flutter_test:
sdk: flutter
timeago: ^3.1.0
shared_preferences: ^2.0.6
http: ^0.13.4
timeago
ライブラリは、Unixタイムスタンプ(1636824843)をa minute ago
のような人間が読める形式に変換しています 、 5 mins ago
など
Once we create a user account, we want to keep track of their
userIdand other minor details. We'll use
そのためのshared_preferencesfor that. Then we'll use the
を使用します HTTP呼び出しを行うためのhttp`ライブラリ。
始めましょう...
構築する最初の画面は、ユーザー作成エンドポイントを使用するユーザー作成画面です。
画面は次のようになります
バニーの写真について心配する必要はありません。 imageviewの単なるプレースホルダー。
lib
内にフォルダを作成します account
というフォルダ 次に、create_profile_screen.dart
という名前の新しいファイルを作成します account
内 フォルダ。
これが私の最終的なlib
の方法です フォルダ構造は次のようになります 新しいユーザーを作成するには、
- プロフィール写真のURL
- 名
- 名前
- ユーザー名
- エンドポイント
コードを見てみましょう
static const String CREATE_USER_PROFILE_URL = "https://5vafvrk8kj.execute-api.us-east-1.amazonaws.com/dev/user";
bool _loading = false;
Future<void>createUserProfile() async{
setState(() {
_loading = true;
});
print(usernameController.text);
print(firstNameController.text);
print(lastNameController.text);
print(profilePicUrl);
await http.post(Uri.parse(CREATE_USER_PROFILE_URL),
body: convert.jsonEncode({'username': usernameController.text,
"firstName":firstNameController.text,"lastName":lastNameController.text,
"profilePic":profilePicUrl})).then((response) async {
var jsonResponse =
convert.jsonDecode(response.body) as Map<String, dynamic>;
setState(() {
_loading = false;
});
if(response.statusCode == 400){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(padding:EdgeInsets.all(10),backgroundColor: Colors.red,content: Text(jsonResponse['message'])));
}else if(response.statusCode == 200) {
print('user id is :' +jsonResponse['userId']);
await saveUserId(jsonResponse['userId']);
Navigator.push(context, MaterialPageRoute(builder: (context){
return HomeScreen();
}));
}
});
}
Futureは、非同期操作を操作するためのコアDartクラスです。 Futureオブジェクトは、将来のある時点で利用可能になる可能性のある値またはエラーを表します。
http.Responseクラスには、成功したhttp呼び出しから受信したデータが含まれています。
上記のコードはhttp post
を使用しています create user endpoint
にPOSTリクエストを送信するメソッド 次に、応答を待ちます。
応答ステータスコードが200の場合、リクエストは成功し、作成されたUserIdを共有設定に保存してから、ホーム画面に移動します。
この画面の完全なソースコードへのリンクは次のとおりです。プロファイルの作成画面。
エンドポイントの1つにより、ユーザーは投稿を作成できました。画面は次のようになります
投稿を作成するには、ユーザーが必要です
- userId
- テキスト
- imageUrl
デモンストレーションの目的で、既製のimageUrlを使用していることを忘れないでください。実際のアプリでは、ユーザーが画像を選択してサーバーにアップロードし、画像のURLを取得してから、それを使用して投稿を作成できるようにする必要があります。
CreatePost
メソッドはCreateUser
に似ています メソッド。
Future<void> createPost(String userId) async {
await http
.post(Uri.parse(CREATE_USER_POST_URL),
body: convert.jsonEncode({
'userId': userId,
"postText": postTextController.text,
"postImage": _postPicUrl[i]
}))
.then((response) async {
var jsonResponse =
convert.jsonDecode(response.body) as Map<String, dynamic>;
setState(() {
_loading = false;
});
if (response.statusCode == 400) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
padding: EdgeInsets.all(10),
backgroundColor: Colors.red,
content: Text(jsonResponse['message'])));
} else if (response.statusCode == 200) {
print('post id is :' + jsonResponse['id']);
Navigator.of(context).pop();
}
});
}
アプリケーションのホーム画面には、作成されたすべての投稿のリストが表示されます。
このようなもの
ストレスのない方法ですべての投稿を取得するには、最初にカスタムダーツオブジェクトを作成する必要があります。単一の投稿を表します。
class Post {
String? postText;
String? userId;
String? createdOn;
String? id;
String? postImage;
PostAdmin? postAdmin;
Post(
{this.postText,
this.userId,
this.createdOn,
this.id,
this.postImage,
this.postAdmin});
Post.fromJson(Map<String, dynamic> json) {
postText = json['postText'];
userId = json['userId'];
createdOn = json['createdOn'];
id = json['id'];
postImage = json['postImage'];
postAdmin = json['postAdmin'] != null
? PostAdmin.fromJson(json['postAdmin'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['postText'] = this.postText;
data['userId'] = this.userId;
data['createdOn'] = this.createdOn;
data['id'] = this.id;
data['postImage'] = this.postImage;
if (this.postAdmin != null) {
data['postAdmin'] = this.postAdmin!.toJson();
}
return data;
}
}
class PostAdmin {
String? timestamp;
String? userId;
String? username;
String? firstName;
String? lastName;
String? profilePic;
PostAdmin(
{this.timestamp,
this.userId,
this.username,
this.firstName,
this.lastName,
this.profilePic});
PostAdmin.fromJson(Map<String, dynamic> json) {
timestamp = json['timestamp'];
userId = json['userId'];
username = json['username'];
firstName = json['firstName'];
lastName = json['lastName'];
profilePic = json['profilePic'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['timestamp'] = this.timestamp;
data['userId'] = this.userId;
data['username'] = this.username;
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['profilePic'] = this.profilePic;
return data;
}
}
次に、http.Response
を変換します そのカスタムDartオブジェクトに。
List<Post> parsePosts(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Post>((json) => Post.fromJson(json)).toList();
}
Future<List<Post>> fetchPosts(http.Client client) async {
final response = await client
.get(Uri.parse(GET_POSTS));
return compute(parsePosts,response.body);
}
fetchPosts
の戻りタイプ メソッドはFuture<List<Post>>
です 。
低速のデバイスでfetchPosts()関数を実行すると、JSONを解析して変換するときに、アプリが一時的にフリーズすることに気付く場合があります。これはジャンクです、そしてあなたはそれを取り除きたいです。
compute
を使用して解析と変換をバックグラウンドに移動することにより、ジャンクを削除します 関数
compute(parsePosts, response.body);
Compute()関数は、バックグラウンド分離で高価な関数を実行し、結果を返します
ホーム画面ファイルでは、FutureBuilderウィジェットを使用して、データベースからすべての投稿をリストとして非同期的に取得します。
2つのパラメータを提供する必要があります:
- 一緒に働きたい未来。この場合、futureはfetchPosts()関数から返されます。
将来の状態(読み込み、成功、エラー)に応じて、Flutterに何をレンダリングするかを指示するビルダー関数。
snapshot.hasDataは、スナップショットにnull以外のデータ値が含まれている場合にのみtrueを返すことに注意してください。
fetchPostsはnull以外の値しか返すことができないため、「404 Not Found」サーバー応答の場合でも、関数は例外をスローする必要があります。例外をスローすると、snapshot.hasErrorがtrueに設定され、エラーメッセージの表示に使用できます。
それ以外の場合は、スピナーが表示されます。
Expanded(child: FutureBuilder<List<Post>>(
future: _posts,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Post>? posts = snapshot.data;
if(posts != null){
return ListView.builder(itemBuilder: (context,index){
return Card(
child: Container(
padding: EdgeInsets.all(10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(1000),
child: Image.network(
posts[index].postAdmin!.profilePic!,
fit: BoxFit.cover,
height: 40,
width: 40,
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(posts[index].postAdmin!.username!,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16),),
Text(posts[index].postText!),
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
posts[index].postImage!,
fit: BoxFit.cover,
height: 150,
width: size.width,
),
),
],
),
),
)
],
),
),
);
},itemCount: posts.length,);
}
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return Container(
height: 40,
width: 40,
child: Center(child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).colorScheme.secondary))));
},
))
initStateメソッドでは、fetchPosts
を呼び出します。late Future<List<Post>> _posts;
@override
void initState() {
// TODO: implement initState
super.initState();
_posts = fetchPosts(http.Client());
}
buildメソッドの代わりにinitStateでfetchPostsを呼び出す理由は、ビュー内の何かを変更する必要があるたびにflutterがbuild()メソッドを呼び出すためです。これは、驚くほど頻繁に発生します。 build()メソッドにfetch呼び出しを残すと、APIが不要な呼び出しで溢れ、アプリの速度が低下します。
完全なソースコードを自由に確認してください
インターフェースを作成するためのエンドポイントはまだいくつかありますが、演習なしの優れたチュートリアルは何ですか?😂
この投稿シリーズでは、Upstashを使用してサーバーレスREST APIを構築し、モバイルアプリケーションで使用する方法について説明しました。
Upstashを使用して次に何を構築するか、またはユースケースに合わせてこのチュートリアルをどのように拡張するかを見てみたいと思います。
この作品が役に立ったと思ったら、ソーシャルメディアページで共有してください。
質問がありますか?コメントを残してください。
エラーを見つけた場合は、何をすべきかを知っています。コメントを残していただければ、できるだけ早くお知らせします。
ハッピーコーディング✌🏿
- ドキュメントのアップスタッシュ
- Redis
- フラッター
- インターネットからのデータの取得
-
Nuxt3とサーバーレスRedisの使用を開始する
はじめに アプリケーションの使用状況を追跡したり、リソースの使用率を制限したり、キャッシュからデータをフェッチしてアプリのパフォーマンスを向上させたりする必要がある場合は、Redisがこれらの要件に対する答えであることがわかります。 Redisは、メモリ内のKey-Valueデータベースです。これはオープンソースであり、RemoteDictionaryServerの略です。 この記事では、Upstash、Redisデータベース、およびVueSSRフレームワークの最近のベータリリースであるNuxt3について説明します。これは、Redisデータベースについて説明する初心者向けの記事で、 Nux
-
Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1
この投稿では、データを保存するためのFlutter、Serverless Framework、Upstash、Redisを使用してサーバーレスモバイルアプリケーションを構築します。 Upstashとは? Upstashは、Redis用のサーバーレスデータベースです。 Upstashを使用すると、リクエストごとに支払います。これは、データベースが使用されていないときに課金されないことを意味します。 Upstashはデータベースを構成および管理します。これは、DynamoDBやFaunaなどの他のデータベースの強力な代替手段であり、などの利点があります。 低レイテンシ REDISAPIと同