इस ट्यूटोरियल श्रृंखला के भाग 2 में आपका स्वागत है। पहले भाग में, हमने देखा कि Upstash, Serverless Framework और Redis का उपयोग करके REST API कैसे बनाया जाता है।
इस भाग में, हम अपने REST API समापन बिंदुओं का उपभोग करने के लिए, Flutter का उपयोग करके एक मोबाइल एप्लिकेशन बनाएंगे।
आइए शुरू करें 🙃
सबसे पहले, आपको अपने कंप्यूटर पर स्पंदन स्थापित और चलाना होगा
- स्पंदन
अपने आईडीई में एक नया स्पंदन प्रोजेक्ट बनाएं और इसे अपनी पसंद का नाम दें।
pubspec.yaml
खोलें अपने स्पंदन प्रोजेक्ट की मूल निर्देशिका में फ़ाइल करें और इन निर्भरताओं को 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
लाइब्रेरी यूनिक्स टाइमस्टैम्प (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` लाइब्रेरी।
आइए शुरू करें...
उपयोगकर्ता बनाएं
पहली स्क्रीन जो हम बना रहे हैं वह है क्रिएट यूजर स्क्रीन, जो क्रिएट यूजर एंडपॉइंट का उपभोग करेगी।
यहां बताया गया है कि स्क्रीन कैसी दिखती है
बन्नी के बारे में चिंता न करें। छविदृश्य के लिए बस एक प्लेसहोल्डर।
lib
. के अंदर एक फोल्डर बनाएं account
नामक फोल्डर और फिर, create_profile_screen.dart
. नामक एक नई फ़ाइल बनाएं account
. के अंदर फ़ोल्डर।
यहां बताया गया है कि मेरा अंतिम lib
कैसे है फ़ोल्डर संरचना की तरह दिखता है नया उपयोगकर्ता बनाने के लिए, हमें एक की आवश्यकता है
- प्रोफ़ाइल तस्वीर का यूआरएल
- पहला नाम
- उपनाम
- उपयोगकर्ता नाम
- समापन बिंदु
आइए कोड देखें
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();
}));
}
});
}
फ्यूचर एसिंक्रोनस ऑपरेशंस के साथ काम करने के लिए एक कोर डार्ट क्लास है। भविष्य की वस्तु एक संभावित मूल्य या त्रुटि का प्रतिनिधित्व करती है जो भविष्य में किसी समय उपलब्ध होगी।
http.Response वर्ग में एक सफल http कॉल से प्राप्त डेटा होता है।
उपरोक्त कोड http post
. का उपयोग करता है create user endpoint
. को पोस्ट अनुरोध भेजने की विधि फिर, प्रतिक्रिया की प्रतीक्षा करें।
यदि प्रतिक्रिया स्थिति कोड 200 है, तो अनुरोध सफल रहा, हम बनाए गए UserId को साझा प्राथमिकताओं में सहेजते हैं, और फिर हम होमस्क्रीन पर चले जाते हैं।
यहां इस स्क्रीन के लिए संपूर्ण स्रोत कोड का लिंक दिया गया है प्रोफ़ाइल स्क्रीन बनाएं।
पोस्ट बनाएं
हमारे अंतिम बिंदुओं में से एक ने उपयोगकर्ता को एक पोस्ट बनाने की अनुमति दी। यहां बताया गया है कि स्क्रीन कैसी दिखती है
एक पोस्ट बनाने के लिए, एक उपयोगकर्ता को चाहिए
- एक उपयोगकर्ता आईडी
- पाठ
- छवियूआरएल
याद रखें कि, प्रदर्शन उद्देश्यों के लिए, हम एक तैयार छवि यूआरएल का उपयोग कर रहे हैं। एक वास्तविक ऐप में, आपको उपयोगकर्ता को अपनी छवि चुनने, उसे सर्वर पर अपलोड करने, छवि यूआरएल प्राप्त करने और फिर पोस्ट बनाने के लिए इसका उपयोग करने की अनुमति देनी होगी।
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
. को रूपांतरित करते हैं उस कस्टम डार्ट ऑब्जेक्ट के लिए।
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);
कंप्यूट () फ़ंक्शन पृष्ठभूमि में महंगे फ़ंक्शन चलाता है और परिणाम देता है
होम स्क्रीन फ़ाइल में, हम आपके डेटाबेस से सूची के रूप में सभी पोस्ट को अतुल्यकालिक रूप से हथियाने के लिए FutureBuilder विजेट का उपयोग करेंगे।
हमें दो पैरामीटर प्रदान करने होंगे:
- वह भविष्य जिसके साथ आप काम करना चाहते हैं। इस मामले में, भविष्य फ़ेचपोस्ट्स () फ़ंक्शन से लौटा।
एक बिल्डर फ़ंक्शन जो फ़्लटर को बताता है कि भविष्य की स्थिति के आधार पर क्या प्रस्तुत करना है:लोडिंग, सफलता या त्रुटि।
ध्यान दें कि स्नैपशॉट। हैसडेटा केवल तभी सही होता है जब स्नैपशॉट में एक गैर-शून्य डेटा मान होता है।
क्योंकि fetchPosts केवल गैर-शून्य मान लौटा सकता है, फ़ंक्शन को "404 नहीं मिला" सर्वर प्रतिक्रिया के मामले में भी एक अपवाद फेंकना चाहिए। एक अपवाद फेंकने से स्नैपशॉट सेट हो जाता है। हैसएरर सही पर सेट हो जाता है जिसका उपयोग एक त्रुटि संदेश प्रदर्शित करने के लिए किया जा सकता है।
अन्यथा, स्पिनर प्रदर्शित किया जाएगा।
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());
}
बिल्ड विधि के बजाय हम initState में fetchPosts को कॉल करने का कारण यह है कि स्पंदन बिल्ड () विधि को हर बार दृश्य में कुछ भी बदलने की आवश्यकता होती है, और यह आश्चर्यजनक रूप से अक्सर होता है। अपने बिल्ड () विधि में फ़ेच कॉल को छोड़ने से एपीआई अनावश्यक कॉलों से भर जाता है और आपके ऐप को धीमा कर देता है।
बेझिझक संपूर्ण स्रोत कोड देखें
इंटरफ़ेस बनाने के लिए अभी भी कुछ समापन बिंदु हैं, लेकिन अभ्यास के बिना एक अच्छा ट्यूटोरियल क्या है 😂
निष्कर्ष
इस पोस्ट श्रृंखला में, हमने देखा कि मोबाइल एप्लिकेशन के माध्यम से उपभोग करते हुए, Upstash के साथ सर्वर रहित रेस्ट API कैसे बनाया जाए।
मुझे यह देखना अच्छा लगेगा कि आप Upstash के साथ आगे क्या बनाते हैं, या आप अपने उपयोग के मामले में इस ट्यूटोरियल को कैसे बेहतर बनाते हैं।
अगर आपको यह लेख मददगार लगा, तो कृपया अपने सोशल मीडिया पेजों पर शेयर करें।
कोई सवाल? एक टिप्पणी छोड़ें।
अगर आपको कोई त्रुटि मिली, तो आप जानते हैं कि क्या करना है। एक टिप्पणी छोड़ दो और मैं इस पर ASAP रहूंगा।
हैप्पी कोडिंग ✌🏿
संदर्भ
- अपस्टैश डॉक्स
- रेडिस
- स्पंदन
- इंटरनेट से डेटा लाया जा रहा है