request method

Future<JsonRestApiResponse> request(
  1. RequestMethod method,
  2. String endpoint, {
  3. dynamic json,
  4. Map<String, dynamic>? queryParameters,
  5. Duration? timeout,
  6. Map<String, String> headers = const {},
})

Perform a request to the API which could either return json data or null. Set method to a valid http method like GET or POST and endpoint to one of the available endpoints of your api like /endpoint.

Send some data using json (can be Map or List) or use the queryParamters.

You can also set a custom timeout duration or add custom headers.

Implementation

Future<JsonRestApiResponse> request(
  RequestMethod method,
  String endpoint, {
  dynamic? json,
  Map<String, dynamic>? queryParameters,
  Duration? timeout,
  Map<String, String> headers = const {},
}) async {
  // Calculate final url
  final url = baseUrl?.resolveUri(
    Uri(
      path: '${baseUrl?.path}$endpoint',
      queryParameters: queryParameters,
    ),
  );
  if (url == null) {
    throw Exception('The baseUrl must bet set before starting a request!');
  }

  // Prepare request
  final request = Request(method.asString, url);
  if (json != null) {
    request.body = jsonEncode(json);
  }

  // Set headers
  if (['PUT', 'POST', 'PATCH'].contains(method)) {
    request.headers['Content-Type'] = 'application/json';
  }
  if (bearerToken != null) {
    request.headers['Authorization'] = 'Bearer $bearerToken';
  }
  for (final entry in headers.entries) {
    request.headers[entry.key] = entry.value;
  }

  try {
    // Start the request
    final response = await httpClient.send(request).timeout(
          timeout ?? Duration(seconds: _timeoutFactor + 5),
        );
    var responseBody = await response.stream.bytesToString();

    // Put arrays into a wrapper map
    List<dynamic>? listResp;
    Map<String, dynamic>? jsonResp;
    var jsonString = String.fromCharCodes(responseBody.runes);
    if (jsonString.isNotEmpty) {
      try {
        final json = jsonDecode(jsonString);
        if (json is Map<String, dynamic>) {
          jsonResp = json;
        } else if (json is List) {
          listResp = json;
        }
      } on FormatException catch (_) {}
    }

    _timeoutFactor = 1;
    final jsonResponse = JsonRestApiResponse(
      endpoint: endpoint,
      method: method,
      raw: jsonString,
      statusCode: response.statusCode,
      jsonObject: jsonResp,
      jsonArray: listResp,
    );

    if (response.statusCode >= 300 || response.statusCode < 200) {
      throw JsonRestApiException.fromJsonRestApiResponse(
        jsonResponse,
        reasonPhrase: response.reasonPhrase,
      );
    }
    return jsonResponse;
  } on TimeoutException catch (_) {
    _timeoutFactor *= 2;
    rethrow;
  }
}