invokeApiMultipart method

Future<Response> invokeApiMultipart({
  1. required Method method,
  2. required String path,
  3. required Map<String, String> fields,
  4. required List<MultipartFile> files,
  5. Map<String, List<String>> queryParameters = const {},
  6. Map<String, String> headerParameters = const {},
  7. AuthRequest? authRequest,
})

Send a multipart/form-data request built from fields (text parts) and files (file parts). The Content-Type header is set by MultipartRequest itself, including the generated boundary — do not pass one via headerParameters.

Implementation

Future<Response> invokeApiMultipart({
  required Method method,
  required String path,
  required Map<String, String> fields,
  required List<MultipartFile> files,
  Map<String, List<String>> queryParameters = const {},
  Map<String, String> headerParameters = const {},
  AuthRequest? authRequest,
}) async {
  if (!method.supportsBody) {
    throw ArgumentError(
      'Multipart body is not allowed for ${method.name} requests',
    );
  }

  final auth = resolveAuth(authRequest);
  final uri = _resolveUri(
    path: path,
    queryParameters: queryParameters,
    auth: auth,
  );

  // MultipartRequest generates its own Content-Type with boundary, so
  // pass null here to avoid appending application/json.
  final headers = _resolveHeaders(
    bodyContentType: null,
    headerParameters: headerParameters,
    auth: auth,
  );

  final request = MultipartRequest(method.name.toUpperCase(), uri)
    ..fields.addAll(fields)
    ..files.addAll(files);
  if (headers != null) {
    request.headers.addAll(headers);
  }

  return _sendWithExceptionMapping(
    method: method,
    path: path,
    send: () async {
      final streamed = await client.send(request);
      return Response.fromStream(streamed);
    },
  );
}