cyber_req 2.0.0
cyber_req: ^2.0.0 copied to clipboard
A flexible API client for Laravel backends with dynamic headers, bearer token support (including FlutterSecureStorage integration), and callbacks for success, failure, and unauthorized handling.
cyber_req - A Robust HTTP Client for Dart/Flutter #
cyber_req is a lightweight, yet powerful and robust HTTP client for Dart and Flutter applications. Built on top of the official http package, it streamlines your API interactions by providing a structured, consistent approach to making requests, handling responses, and managing common scenarios such as authentication, error handling, and token management—including support for Flutter Secure Storage tokens.
Table of Contents #
Features #
- Simplified API Calls: Intuitive methods (
post,get,put,delete) covering all common HTTP verbs. - Automatic JSON Handling: Sends JSON bodies and parses JSON responses by default.
- Flexible Headers: Configure global default headers with per-request overrides.
- Bearer Token Support: Automatically attach bearer tokens, optionally retrieved from Flutter Secure Storage.
- Secure Storage Integration: Use tokens securely stored on device without manually fetching them in your code.
- Robust Error Handling: Custom exceptions (
ApiException,UnauthorizedException) that encapsulate networking issues, invalid responses, and API errors. - Unauthorized Handling Callback: Define an
onUnauthorizedcallback to handle 401 errors, useful for token refresh or user logout workflows. - Success and Failure Callbacks: Optional per-request callbacks for granular response and error handling.
- Customizable Status Codes: Allow non-2xx HTTP status codes to be treated as success when required.
Installation #
Add to your pubspec.yaml:
```yaml
dependencies:
cyber_req: ^2.0.0
http: ^0.13.5
flutter_secure_storage: ^8.0.0
Run:
```bash
flutter pub get
```
---
## Usage
### Basic Initialization
```dart
import 'package:cyber_req/cyber_req.dart';
final apiService = ApiService(
baseUrl: 'https://api.yourapp.com/v1',
defaultHeaders: {
'X-App-Version': '1.0.0',
'Accept-Language': 'en-US',
},
onUnauthorized: () async {
// Handle 401 Unauthorized globally (e.g. refresh token or logout)
},
);
```
### Making a POST Request
```dart
final response = await apiService.post(
'users',
data: {
'name': 'Alice Smith',
'email': 'alice.smith@example.com',
'password': 'securepassword123',
},
extraHeaders: {'X-Request-ID': 'unique-post-id-123'},
onSuccess: (data) {
print('User created successfully: $data');
},
onFailure: (error) {
print('Failed to create user: ${error.message} (Status: ${error.statusCode})');
},
);
```
### Making a GET Request with Query Parameters
```dart
final response = await apiService.get(
'products',
queryParams: {
'category': 'electronics',
'limit': 20,
'sort_by': 'price_asc',
},
extraHeaders: {'Cache-Control': 'no-cache'},
);
```
### Making PUT and DELETE Requests
```dart
await apiService.put(
'products/123',
data: {'price': 199.99},
);
await apiService.delete(
'products/123',
onSuccess: (data) => print('Product deleted successfully'),
);
```
### Handling Custom Status Codes
```dart
await apiService.post(
'forms/submit',
data: {'field': 'value'},
allowedStatusCodes: [409], // Treat 409 Conflict as success
);
```
### Using Secure Storage Tokens
To automatically use the bearer token stored in Flutter Secure Storage under key `token`, set `useStorageToken: true` on any request:
```dart
final response = await apiService.get(
'user/profile',
useStorageToken: true,
);
```
This removes the need to manually fetch or provide tokens in your code, ensuring security and convenience.
### Disposing the ApiService
Close the internal HTTP client when done to free resources:
```dart
apiService.dispose();
```
---
## Error Handling
Use try-catch blocks to handle errors explicitly:
```dart
try {
final data = await apiService.get('user/profile', useStorageToken: true);
print(data);
} on UnauthorizedException {
print('Unauthorized access - please login.');
} on ApiException catch (e) {
print('API Error: ${e.message} (Status: ${e.statusCode})');
} catch (e) {
print('Unexpected error: $e');
}
```
---
## API Reference
### `ApiService`
**Constructor:**
```dart
ApiService({
required String baseUrl,
String? bearerToken,
http.Client? httpClient,
UnauthorizedHandler? onUnauthorized,
Map<String, String>? defaultHeaders,
})
```
**Methods:**
* `Future<Map<String, dynamic>> post(
String endpoint, {
Map<String, dynamic>? data,
Map<String, String>? extraHeaders,
String? bearerToken,
bool useStorageToken = false,
SuccessCallback? onSuccess,
FailureCallback? onFailure,
List<int>? allowedStatusCodes
})`
* `Future<Map<String, dynamic>> get(
String endpoint, {
Map<String, dynamic>? queryParams,
Map<String, String>? extraHeaders,
String? bearerToken,
bool useStorageToken = false,
SuccessCallback? onSuccess,
FailureCallback? onFailure,
List<int>? allowedStatusCodes
})`
* `Future<Map<String, dynamic>> put(
String endpoint, {
Map<String, dynamic>? data,
Map<String, String>? extraHeaders,
String? bearerToken,
bool useStorageToken = false,
SuccessCallback? onSuccess,
FailureCallback? onFailure,
List<int>? allowedStatusCodes
})`
* `Future<Map<String, dynamic>> delete(
String endpoint, {
Map<String, String>? extraHeaders,
String? bearerToken,
bool useStorageToken = false,
SuccessCallback? onSuccess,
FailureCallback? onFailure,
List<int>? allowedStatusCodes
})`
* `void dispose()`
---
## Contributing
Contributions, issues, and feature requests are welcome. Feel free to check the [issues page](https://github.com/cyberwizard-dev/cyber_req/issues) and submit pull requests.
Consider supporting the project by buying me a coffee via Opay: `8169795832`.
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.