Hey @aloisdeniel
I noticed there is currently no support for Multipart request. I went ahead and added an extension to the extension. :)
extension ExtendedClientX on ExtendedClient {
Future<http.Response> formWithOptions(
String url, {
@required Map<String, dynamic> data,
Map<String, io.File> files,
Map<String, String> headers,
List<dynamic> options,
}) async {
assert(data != null);
final request = http.MultipartRequest("POST", Uri.parse(url));
request.fields..addAll(_encodeFormBody(data));
if (files != null) {
for (final item in files.entries) {
request.files.add(
await http.MultipartFile.fromPath(item.key, item.value.path),
);
}
}
return sendWithOptions(
request,
<dynamic>[
...options,
JsonRequestOptions({...headers, io.HttpHeaders.contentTypeHeader: "application/x-www-form-urlencoded"})
],
).then(http.Response.fromStream);
}
String encodeBody(dynamic value) => json.encode(value);
Map<String, String> _encodeFormBody(Map<String, dynamic> data) {
return data.map((key, dynamic value) => MapEntry(key, _isPrimitiveValue(value) ? value : encodeBody(value)));
}
bool _isPrimitiveValue(dynamic value) {
return [int, double, bool, String].contains(value.runtimeType);
}
}
And another helper extension for sugar.
class JsonRequestOptions {
const JsonRequestOptions([this.headers = const {}]);
final Map<String, String> headers;
}
class JsonRequestExtension extends Extension<JsonRequestOptions> {
JsonRequestExtension([
JsonRequestOptions defaultOptions = const JsonRequestOptions(
{io.HttpHeaders.acceptHeader: mime, io.HttpHeaders.contentTypeHeader: mime},
),
]) : super(defaultOptions: defaultOptions);
static const mime = "application/json";
@override
Future<http.StreamedResponse> sendWithOptions(http.BaseRequest request, JsonRequestOptions options) {
final headers = Map<String, String>.from(defaultOptions.headers);
if (options.headers != null && options.headers.isNotEmpty) {
headers.addAll(options.headers);
}
if (headers.isNotEmpty) {
request.headers.addAll(headers);
}
return super.sendWithOptions(request, options);
}
}
This seemed to cover all my cases, tests passed and all.
Then, I also found the retry extension useful and realised I needed it too. Only issue now is the _copyRequest
method. This eagerly tries to make a copy of the BaseRequest
. As that is the only supported variant, it completely ignores the files
and fields
property of the multipart request. To solve this, we would need a more elegant approach. Hence the long story.
Also, nice work with the extensions. 👍