http_wrap 1.3.3 copy "http_wrap: ^1.3.3" to clipboard
http_wrap: ^1.3.3 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 calling request
  • defaultHeaders: Headers automatically added to every request
  • timeout: 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/books
  • baseUrl: Per-request base URL override
  • fields: JSON body fields (or multipart form fields)
  • queryParams: URL query parameters
  • headers: Per-request headers
  • requestFiles: 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 #

  • null values in fields are automatically removed before sending.
  • In multipart requests, List and Map values 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 message values.
  • For non-2xx responses, success is false and errorData contains server error details.

License #

This project is licensed under the MIT License. See LICENSE for details.

0
likes
0
points
256
downloads

Publisher

unverified uploader

Weekly Downloads

A lightweight Dart and Flutter HTTP wrapper with shared configuration, multipart uploads, and unified responses.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, http, plugin_platform_interface

More

Packages that depend on http_wrap

Packages that implement http_wrap