mcpField
F
flutter-use-http-package

flutter-use-http-package

github.com/dhruvanbhalara開発3044 回インストール9 週間前に更新
リポジトリ

flutter-use-http-package について

Dart の `http` パッケージで REST クライアントを構築する Flutter 開発スキルです。リクエスト処理、エラー対応、テスト、バックグラウンドでの JSON 解析を扱います。

主な機能

  1. 01HTTP クライアントと権限の設定
  2. 02REST リクエストとレスポンス処理
  3. 03ステータス確認とエラー対応
  4. 04モック用クライアントの注入
  5. 05`compute()` によるバックグラウンド JSON 解析

活用シーン

  1. 01Flutter アプリでの REST 呼び出し実装
  2. 02モッククライアントを使ったネットワーククラスのテスト
  3. 03UI スレッド外での大きな JSON の解析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dhruvanbhalara/skills --skill flutter-use-http-package

インストール後、Claude Code で/flutter-use-http-packageを入力して読み込まれたか確認します。

詳細

目次

設定と権限

ネットワークリクエストを有効にするには、開発環境とプラットフォーム固有のアクセス制御を設定します。

  1. ターミナルで http 依存関係を追加します。
    flutter pub add http
    
  2. Dart ファイルでエイリアスを付けてライブラリをインポートします。
    import 'package:http/http.dart' as http;
    
  3. <manifest> タグ内の android/app/src/main/AndroidManifest.xml を変更して、Android のインターネット権限を有効にします。
    <uses-permission android:name="android.permission.INTERNET" />
    
  4. <dict> タグ内の macos/Runner/DebugProfile.entitlements と macos/Runner/Release.entitlements を変更して、macOS のインターネットクライアントを有効にします。
    <key>com.apple.security.network.client</key>
    <true/>
    

リクエストの実行とレスポンスの処理

次のベストプラクティスを適用して、信頼性の高い REST クライアントを設計します。

  • 厳密な URL 解析:エンドポイント文字列は必ず Uri.parse('url') で解析します。クライアントの呼び出しに生の文字列を渡してはいけません。
  • ヘッダーと認証:認証、受け入れ形式、コンテンツタイプの設定をすべて付与します。dart:io の HttpHeaders.authorizationHeader キーを使用してアクセストークンを挿入します。
  • ペイロードのエンコード:リソースの状態を変更する場合(POST、PUT)、dart:convert の jsonEncode でペイロード本文をエンコードします。
  • ステータスの検証:レスポンスコードを検証します。明示的な成功ステータスコード(例:200 OK または 201 Created)のみを処理します。
  • エラー時は例外をスロー:サーバーが失敗を示すステータスコードを返した場合は、内容の分かる例外をスローします。失敗時に null を返してはいけません。問題が隠れ、UI の読み込みスピナーが無限に表示される原因になります。
  • クライアントのモック化:標準のグローバルメソッドを呼び出す代わりに、ネットワーククラスで http.Client 依存関係を受け取ります。これにより、テストやモックの注入が容易になります。

バックグラウンドでの解析

1 MB を超えるペイロードを処理する際に UI のカクつき(フレームのドロップ)を防ぐには、JSON のデコードとマッピングをバックグラウンドスレッドに移します。

  • package:flutter/foundation.dart をインポートします。
  • compute() 関数内で解析ロジックを実行し、バックグラウンドのアイソレートを起動します。
  • 解析関数はトップレベル関数または静的クラスメソッドとして定義します。クロージャーや通常のインスタンスメソッドはアイソレート境界を越えられません。

ワークフロー:ネットワーク操作の実行

ネットワーク連携を構築して検証するには、次のチェックリストに従います。

  • モデルの契約を定義する:カスタムの fromJson ファクトリーコンストラクターを備えた、明確で不変のモデルクラスを作成します。
  • HTTP クライアントを用意する:http.Client を受け取るネットワーククライアントクラスを作成します。
  • リクエストを作成する:
    • 読み取り(GET)の場合:クエリパラメーターを URI に付与します。
    • 変更(POST/PUT)の場合:'Content-Type': 'application/json; charset=UTF-8' を設定し、jsonEncode のデータを付与します。
    • 削除(DELETE)の場合:200 OK に一致した際に、成功を示す値または空のモデルマッピングを返します。
  • エラー処理を徹底する:成功以外のステータスコードに対して、意味のある例外をスローします。
  • UI の状態と連携する:UI レイヤーでネットワークリクエストを FutureBuilder または状態管理コントローラーにバインドします。
  • 境界条件を検証する:適切な読み込み画面、エラーダイアログ、オフライン時のフィードバックループを用いてテストします。

例

完全なネットワーククライアントとアイソレートパーサー

この例では、複雑なペイロードリストをバックグラウンドのアイソレートで解析する、信頼性が高くテスト可能なネットワーククライアントの設定方法を示します。

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class Article {
  final int id;
  final String title;

  const Article({required this.id, required this.title});

  factory Article.fromJson(Map<String, dynamic> json) {
    return Article(
      id: json['id'] as int,
      title: json['title'] as String,
    );
  }
}

// Top-level function for background isolate computation
List<Article> parseArticles(String responseBody) {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
  return parsed.map<Article>((json) => Article.fromJson(json)).toList();
}

class ApiService {
  final http.Client client;

  ApiService({http.Client? client}) : client = client ?? http.Client();

  Future<List<Article>> fetchArticles() async {
    final response = await client.get(
      Uri.parse('https://jsonplaceholder.typicode.com/posts'),
      headers: {
        HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
        HttpHeaders.acceptHeader: 'application/json',
      },
    );

    if (response.statusCode == 200) {
      // Offload to background isolate
      return compute(parseArticles, response.body);
    } else {
      throw HttpException('Failed to load articles: ${response.statusCode}');
    }
  }
}

コメント