Flutter http 简单封装

367 阅读1分钟

新手,请指点,

封装目的

  • 统一处理header
  • 支持api短名称
  • 支持query parameters
  • 预处理response

注意

本封装只支持接口返回数据为json格式

http.dart

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

const API_HOST = 'https://api-dev.example.com';

class RequestOptions {
  final Map<String, String> params;

  RequestOptions({this.params});
}

class _HttpService {
  bool _isExternalUrl(String url) {
    final RegExp regExp = new RegExp(r"^https?://");

    if (regExp.hasMatch(url)) {
      return true;
    }

    return false;
  }

  Uri _parseUrl(String url, RequestOptions options) {
    if (false == this._isExternalUrl(url)) {
      List<String> split = url.split(':');

      if (split[0] == 'api') {
        split.removeAt(0);
        url = API_HOST + split.join(':');
      } else {
        url = split.join(':');
      }
    }

    Uri result = Uri.parse(url);
    if (options != null && options.params != null) {
      result = result.replace(queryParameters: options.params);
    }

    return result;
  }

  Map<String, String> _parseHeader(String url, bool withContentType) {
    Map<String, String> header = {};

    if (withContentType == true) {
      header['Content-Type'] = 'application/json; charset=UTF-8';
    }
    
    if (this._isExternalUrl(url) != true) {
      // TODO:读取本地缓存中的token
      header['token'] = 'xxx';
    }

    return header;
  }

  dynamic _responseHandler(http.Response response) {
    Map<String, dynamic> body;

    try {
      body = json.decode(response.body);
    } catch (e) {
      body = {
        'code': 'unknown',
      };
    }

    if (response.statusCode == 200 || response.statusCode == 201) {
      return body;
    } else {
      throw Exception(body);
    }
  }

  Future<dynamic> post(String url, Map<String, dynamic> data,
      [RequestOptions options]) async {
    final http.Response response = await http.post(
      this._parseUrl(url, options),
      headers: this._parseHeader(url, true),
      body: jsonEncode(data),
    );

    return this._responseHandler(response);
  }

  Future<dynamic> get(String url, [RequestOptions options]) async {
    final http.Response response = await http.get(
      this._parseUrl(url, options),
      headers: this._parseHeader(url, false),
    );

    return this._responseHandler(response);
  }
}

final _HttpService httpService = _HttpService();

使用范例

import 'package:pertaste/services/http.dart';

class User {
  final String id;
  final String name;
  final String email;
  final String avatar;
  final String gender;

  User({
    this.id,
    this.name,
    this.email,
    this.avatar,
    this.gender,
  });

  factory User.assign(Map<String, dynamic> user) {
    return User(
      id: user['id'],
      name: user['name'],
      email: user['email'],
      avatar: user['avatar'],
      gender: user['gender'],
    );
  }
}

class _MemberService {
  Future<User> login(String account, String password) async {
    final parsedAccount = parseAccount(account);

    try {
      final response = await httpService.post('api:/member/login', {
        'type': parsedAccount.type,
        'account': parsedAccount.value,
        'password': password,
      });

      return User.assign(response);
    } catch (e) {
      throw Exception(e);
    }
  }
}

final memberService = _MemberService();