Kodokon kodokon.com

किसी HTTP API को कॉल करना: डिकोडिंग और स्क्रीन की अवस्थाएँ

http पैकेज के साथ एक पेशेवर नेटवर्क कॉल की संरचना बनाएँ: टाइमआउट, स्टेटस कोड, टाइप की गई डिकोडिंग और संपूर्ण अवस्थाएँ।

11 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

http पैकेज बुनियादी चीज़ों को कवर करता है: अनुरोध, हेडर, बॉडी। dio इंटरसेप्टर, रद्दीकरण और रीट्राई जोड़ता है, जिसकी कीमत एक भारी डिपेंडेंसी है - एक अच्छा विकल्प जब ऐप कुछ एंडपॉइंट से आगे बढ़ जाता है। क्लाइंट चाहे जो भी हो, किसी गंभीर नेटवर्क कॉल की संरचना नहीं बदलती: एक टाइमआउट, HTTP स्टेटस कोड की एक जाँच, एक टाइप किया गया डिकोड, और स्पष्ट रूप से संभाली गई तीन स्क्रीन अवस्थाएँ (लोडिंग, त्रुटि, डेटा)।

BASH
flutter pub add http
DART
import 'dart:convert';

import 'package:http/http.dart' as http;

class Article {
  const Article({required this.title});

  factory Article.fromJson(Map<String, dynamic> json) =>
      Article(title: json['title'] as String);

  final String title;
}

Future<List<Article>> fetchArticles() async {
  final uri = Uri.https('api.example.com', '/articles');
  final response = await http
      .get(uri)
      .timeout(const Duration(seconds: 8));
  if (response.statusCode != 200) {
    throw Exception('HTTP ${response.statusCode}');
  }
  final body = utf8.decode(response.bodyBytes);
  final data = jsonDecode(body) as List<dynamic>;
  return [
    for (final item in data)
      Article.fromJson(item as Map<String, dynamic>),
  ];
}
टाइमआउट, स्टेटस जाँचा गया, UTF-8 डिकोड फिर टाइपिंग।

दो व्यवहार अक्सर लोगों को चौंका देते हैं। एक: http किसी 404 या 500 स्टेटस पर कोई अपवाद नहीं फेंकता - नेटवर्क के दृष्टिकोण से अनुरोध "सफल" रहा, इसलिए statusCode की जाँच करना आप पर निर्भर है। दो: jsonDecode dynamic लौटाता है; टाइपिंग बहाल करने के लिए तुरंत कास्ट करें (as List<dynamic>, as Map<String, dynamic>)। बड़े पेलोड के लिए, डिकोड को compute के साथ किसी आइसोलेट पर सौंप दें ताकि आप UI को फ़्रीज़ न करें।

बचता है स्क्रीन की अवस्था को दर्शाना। error != null के साथ जुड़े isLoading जैसे बूलियन फ़्लैग हमेशा असंगत अवस्थाओं में पहुँच जाते हैं (एक ही समय पर लोडिंग और त्रुटि)। एक sealed क्लास अवस्थाओं को परस्पर अनन्य और switch को संपूर्ण बना देती है: यदि आप कल कोई अवस्था जोड़ते हैं, तो कंपाइलर आपको अपडेट करने के लिए हर स्क्रीन बता देगा।

DART
import 'package:flutter/material.dart';

sealed class ArticlesState {
  const ArticlesState();
}

class ArticlesLoading extends ArticlesState {
  const ArticlesLoading();
}

class ArticlesError extends ArticlesState {
  const ArticlesError(this.message);

  final String message;
}

class ArticlesLoaded extends ArticlesState {
  const ArticlesLoaded(this.titles);

  final List<String> titles;
}

Widget buildArticlesBody(ArticlesState state) {
  return switch (state) {
    ArticlesLoading() => const Center(
        child: CircularProgressIndicator(),
      ),
    ArticlesError(:final message) => Center(
        child: Text(message),
      ),
    ArticlesLoaded(:final titles) => ListView.builder(
        itemCount: titles.length,
        itemBuilder: (context, index) => ListTile(
          title: Text(titles[index]),
        ),
      ),
  };
}
एक संपूर्ण switch: कोई अवस्था भुलाई नहीं जा सकती।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. आपकी http.get कॉल को एक 500 प्रतिक्रिया मिलती है। http पैकेज क्या करता है?
    • यह एक अपवाद फेंकता है जिसे आप try/catch से पकड़ सकते हैं।
    • यह Response को सामान्य रूप से लौटाता है: statusCode की जाँच करना आप पर निर्भर है।
    • यह अनुरोध को स्वचालित रूप से तीन बार दोबारा चलाता है।
  2. प्राप्त डेटा में उच्चारण-चिह्न वाले अक्षर गलत तरीके से प्रदर्शित होते हैं। सबसे संभावित कारण?
    • jsonDecode UTF-8 को नहीं संभालता।
    • Flutter किसी समर्पित पैकेज के बिना उच्चारण-चिह्न वाले अक्षर प्रदर्शित नहीं कर सकता।
    • सर्वर charset छोड़ देता है: तब response.body को latin-1 के रूप में डिकोड किया जाता है; utf8.decode(response.bodyBytes) का उपयोग करें।
  3. किसी स्क्रीन की अवस्था को मॉडल करने के लिए sealed क्लास का निर्णायक लाभ क्या है?
    • switch संपूर्ण हो जाता है: कंपाइलर किसी भी असंभाली गई अवस्था को चिह्नित कर देता है।
    • यह स्क्रीन को तेज़ी से रेंडर करता है।
    • यह आपको विजेट को रीबिल्ड किए बिना अवस्था बदलने देता है।