defaultFetch function

Future<Map<String, dynamic>> defaultFetch({
  1. required String endpoint,
  2. String? host,
  3. String? defaultHost,
  4. FetchMethod method = FetchMethod.post,
  5. Map<String, String>? baseHeaders,
  6. Map<String, String>? headers,
  7. Duration? timeout = defaultTimeout,
  8. bool cbor = true,
  9. dynamic body,
})

defaultFetch is a wrapper of http.get, which can be replaced by any other http packages (e.g. dio). http has embedded by default, so the library use it directly. Users can set host should be full path of http/https. Usually the usage could be defaultHost+endpoint and set the defaultHost to somewhere final, then change the endpoint programmatically. defaultTimeout is the default timeout limit, and throw error directly to end the request section.

Implementation

Future<Map<String, dynamic>> defaultFetch({
  required String endpoint,
  String? host,
  String? defaultHost,
  FetchMethod method = FetchMethod.post,
  Map<String, String>? baseHeaders,
  Map<String, String>? headers,
  Duration? timeout = defaultTimeout,
  bool cbor = true,
  dynamic body,
}) async {
  final client = http.Client();
  try {
    final uri = Uri.parse(host ?? '$defaultHost$endpoint');
    Future<http.Response> fr;
    final compactHeaders = {...?baseHeaders, ...?headers};
    if (cbor) {
      compactHeaders['Content-Type'] = 'application/cbor';
    }
    switch (method) {
      case FetchMethod.post:
        fr = client.post(uri, headers: compactHeaders, body: body);
        break;
      case FetchMethod.get:
        fr = client.get(uri, headers: {...?baseHeaders, ...?headers});
        break;
      case FetchMethod.head:
        fr = client.head(uri, headers: {...?baseHeaders, ...?headers});
        break;
      case FetchMethod.put:
        fr = client.put(uri, headers: compactHeaders, body: body);
        break;
      case FetchMethod.delete:
        fr = client.delete(uri, headers: compactHeaders, body: body);
        break;
      case FetchMethod.patch:
        fr = client.patch(uri, headers: compactHeaders, body: body);
        break;
      case FetchMethod.connect:
      case FetchMethod.options:
      case FetchMethod.trace:
        throw UnimplementedError(
          'HTTP request method: '
          '`${method.name.toUpperCase()}` not implemented.',
        );
    }

    final duration = timeout ?? defaultTimeout;
    final response = await fr.timeout(
      duration,
      onTimeout: () => throw TimeoutException(
        '${host ?? '$defaultHost$endpoint'} timeout.',
        duration,
      ),
    );
    if (response.headers['content-type'] != null &&
        response.headers['content-type']!.split(',').length > 1) {
      final actualHeader = response.headers['content-type']!.split(',').first;
      response.headers['content-type'] = actualHeader;
    }
    return {
      'body': response.body,
      'ok': response.statusCode >= 200 && response.statusCode < 300,
      'statusCode': response.statusCode,
      'statusText': response.reasonPhrase ?? '',
      'arrayBuffer': response.bodyBytes,
    };
  } finally {
    client.close();
  }
}