invokeAPI method

Future<Response> invokeAPI(
  1. String path,
  2. String method,
  3. List<QueryParam> queryParams,
  4. Object body,
  5. Map<String, String> headerParams,
  6. Map<String, String> formParams,
  7. String nullableContentType,
  8. List<String> authNames,
)

Implementation

Future<Response> invokeAPI(
  String path,
  String method,
  List<QueryParam> queryParams,
  Object body,
  Map<String, String> headerParams,
  Map<String, String> formParams,
  String nullableContentType,
  List<String> authNames,
) async {
  _updateParamsForAuth(authNames, queryParams, headerParams);

  headerParams.addAll(_defaultHeaderMap);

  final urlEncodedQueryParams = queryParams
    .where((param) => param.value != null)
    .map((param) => '$param');

  final queryString = urlEncodedQueryParams.isNotEmpty
    ? '?${urlEncodedQueryParams.join('&')}'
    : '';

  final uri = Uri.parse('$basePath$path$queryString');

  if (nullableContentType != null) {
    headerParams['Content-Type'] = nullableContentType;
  }

  try {
    // Special case for uploading a single file which isn't a 'multipart/form-data'.
    if (
      body is MultipartFile && (nullableContentType == null ||
      !nullableContentType.toLowerCase().startsWith('multipart/form-data'))
    ) {
      final request = StreamedRequest(method, uri);
      request.headers.addAll(headerParams);
      request.contentLength = body.length;
      body.finalize().listen(
        request.sink.add,
        onDone: request.sink.close,
        // ignore: avoid_types_on_closure_parameters
        onError: (Object error, StackTrace trace) => request.sink.close(),
        cancelOnError: true,
      );
      final response = await _client.send(request);
      return Response.fromStream(response);
    }

    if (body is MultipartRequest) {
      final request = MultipartRequest(method, uri);
      request.fields.addAll(body.fields);
      request.files.addAll(body.files);
      request.headers.addAll(body.headers);
      request.headers.addAll(headerParams);
      final response = await _client.send(request);
      return Response.fromStream(response);
    }

    final msgBody = nullableContentType == 'application/x-www-form-urlencoded'
      ? formParams
      : await serializeAsync(body);
    final nullableHeaderParams = headerParams.isEmpty ? null : headerParams;

    switch(method) {
      case 'POST': return await _client.post(uri, headers: nullableHeaderParams, body: msgBody,);
      case 'PUT': return await _client.put(uri, headers: nullableHeaderParams, body: msgBody,);
      case 'DELETE': return await _client.delete(uri, headers: nullableHeaderParams, body: msgBody,);
      case 'PATCH': return await _client.patch(uri, headers: nullableHeaderParams, body: msgBody,);
      case 'HEAD': return await _client.head(uri, headers: nullableHeaderParams,);
      case 'GET': return await _client.get(uri, headers: nullableHeaderParams,);
    }
  } on SocketException catch (e, trace) {
    throw ApiException.withInner(HttpStatus.badRequest, 'Socket operation failed: $method $path', e, trace,);
  } on TlsException catch (e, trace) {
    throw ApiException.withInner(HttpStatus.badRequest, 'TLS/SSL communication failed: $method $path', e, trace,);
  } on IOException catch (e, trace) {
    throw ApiException.withInner(HttpStatus.badRequest, 'I/O operation failed: $method $path', e, trace,);
  } on ClientException catch (e, trace) {
    throw ApiException.withInner(HttpStatus.badRequest, 'HTTP connection failed: $method $path', e, trace,);
  } on Exception catch (e, trace) {
    throw ApiException.withInner(HttpStatus.badRequest, 'Exception occurred: $method $path', e, trace,);
  }

  throw ApiException(HttpStatus.badRequest, 'Invalid HTTP operation: $method $path',);
}