http_wrap 1.3.5
http_wrap: ^1.3.5 copied to clipboard
A lightweight Dart and Flutter HTTP wrapper with shared configuration, multipart uploads, and unified responses.
http_wrap #
A lightweight Dart/Flutter wrapper around the http package to make API calls
simpler.
Set your request values (fields, headers, queryParams, requestFiles,
etc.) and call one method.
Features #
- Simple, single entry-point request API
- Base URL and default header configuration
- Query params support
- JSON request body support
- Multipart/form-data support for file uploads
- File download support (pause, resume, download progress, cancel)
- Unified response object (
HttpResponse) - Structured error metadata (
errorCode,errorData) for failed requests - Basic timeout and network error handling
Installation #
Add to your pubspec.yaml:
dependencies:
http_wrap: ^1.3.0
Then run:
flutter pub get
Quick Start #
import 'package:http_wrap/http_wrap.dart';
final api = HttpWrap()
..config(
baseUrl: 'https://fakerapi.it',
timeout: 30,
defaultHeaders: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
);
GET Request With Query Params #
final res = await api.request(
method: .get,
endpoint: '/api/v2/books',
queryParams: {
'_quantity': '5',
'_locale': 'en_US',
},
);
if (res.success) {
print(res.data);
} else {
print(res.message);
}
POST Request With JSON Body #
final res = await api.request(
method: .post,
endpoint: '/api/v1/users',
fields: {
'name': 'John Doe',
'email': 'john@acme.com',
},
headers: {
'Authorization': 'Bearer your_token_here',
},
);
Multipart/Form-Data Request (File Upload) #
import 'package:http_wrap/http_wrap.dart';
final res = await api.request(
method: .post,
endpoint: '/api/v1/upload',
useFormData: true,
fields: {
'title': 'Profile photo',
},
requestFiles: [
RequestFileFromPath(itemKey: 'file', path: '/absolute/path/to/image.jpg'),
],
);
File Download #
NOTE: This download function doesn't check the validity of the URL or the save directory. Make sure to handle any necessary permissions and validations before calling this function.
The GOOD news is when you start a download, you can close/stop the app entirely, come back to the app and if the download url is the same, the package will automatically resume from the exact point where it was interupted. The only thing to keep safe is the download url.
final downloadController = api.download(
url: 'https://example.com/files/report.pdf',
saveDirectory: '/absolute/path/to/save/directory',
);
// Use the controller to get the progress stream
downloadController.progressStream.listen((info) {
print('State: ${info.state}');
print('Progress: ${info.progress?.toStringAsFixed(2)}%');
print('Can resume: ${info.canResume}');
});
// Use the controller to PAUSE the current download stream.
downloadController.pause();
// Use the controller to RESUME the paused download stream.
downloadController.resume();
// Cancel and cleanup any partial file.
await downloadController.cancel();
// Use the controller to see whether the stream is paused.
downloadController.isPaused();
API Reference #
config #
void config({
String? baseUrl,
Map<String, String>? defaultHeaders,
int? timeout,
})
baseUrl: Default host/base URL used when callingrequestdefaultHeaders: Headers automatically added to every requesttimeout: Timeout in seconds (default:100)
request #
Future<HttpResponse> request({
required HttpMethod method,
required String endpoint,
String? baseUrl,
Map<String, dynamic>? fields,
Map<String, dynamic>? queryParams,
Map<String, String>? headers,
@Deprecated('Use requestFiles instead.')
List<({String key, String? path})> files = const [],
List<RequestFile> requestFiles = const [],
bool useFormData = false,
})
method: HTTP method (.get,.post,.put,.patch,.delete)endpoint: API route, example:/api/v2/booksbaseUrl: Per-request base URL overridefields: JSON body fields (or multipart form fields)queryParams: URL query parametersheaders: Per-request headersrequestFiles: Files for multipart requests (RequestFileFromPath,RequestFileFromBytes,RequestFileFromString)files: Deprecated. Backward-compatible multipart files using(key, path)useFormData: Force multipart/form-data
Response Shape #
Every request returns HttpResponse:
class HttpResponse {
final String? message;
final dynamic data;
final bool success;
final ({int? errorCode, dynamic errorData})? errorData;
}
Typical checks:
if (response.success) {
// handle response.data
} else {
// handle response.message
print(response.errorData?.errorCode);
print(response.errorData?.errorData);
}
Notes #
nullvalues infieldsare automatically removed before sending.- In multipart requests,
ListandMapvalues are encoded using bracketed form keys (for example:items[0],items[1],meta[name]) so backends like Laravel/PHP can parse them as arrays/objects. - Explicit empty lists cannot be represented directly in multipart form fields.
Empty lists are omitted; normalize them to
[]on the server if needed. - For multipart requests, avoid manually setting
content-type; it is handled internally. - Network and timeout errors are converted to readable
messagevalues. - For non-2xx responses,
successisfalseanderrorDatacontains server error details.
License #
This project is licensed under the MIT License. See LICENSE for details.