RestEz
A comprehensive and easy-to-use REST API client package for Flutter applications with built-in error handling, timeout management, and web file download support.
Features
- 🚀 Easy to use: Simple API for GET, POST, PATCH, and DELETE requests
- 🔒 Built-in authentication: Automatic Bearer token handling
- ⏱️ Timeout management: Configurable request timeouts
- 🎯 Type safety: Generic responses with proper type casting
- 📝 Error handling: Comprehensive error handling with interceptors
- 🌐 Web support: File download and PDF printing for web platforms
- 🔧 Configurable: Flexible configuration options
- 📊 Logging: Optional debug logging for development
Installation
Add this to your package's pubspec.yaml file:
dependencies:
rest_ez: ^0.1.0
Then run:
flutter pub get
Usage
Basic Setup
import 'package:rest_ez/rest_ez.dart';
void main() {
// Initialize the client
RestEzClient.instance.initialize(
config: const RestEzConfig(
baseUrl: 'https://api.example.com',
defaultTimeout: Duration(seconds: 30),
enableLogging: true,
),
);
// Set authentication token
RestEzClient.instance.setAuthToken('your_bearer_token');
runApp(MyApp());
}
Making Requests
GET Request
// Define your data model
class User {
final int id;
final String name;
final String email;
User({required this.id, required this.name, required this.email});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
email: json['email'],
);
}
}
// Make a GET request
final response = await RestEzClient.instance.get<User>(
endpoint: '/users/1',
fromJson: (json) => User.fromJson(json),
queryParameters: {'include': 'profile'},
);
if (response.success) {
User user = response.data!;
print('User: ${user.name}');
} else {
print('Error: ${response.error}');
}
POST Request
final response = await RestEzClient.instance.post<User>(
endpoint: '/users',
body: {
'name': 'John Doe',
'email': 'john@example.com',
},
fromJson: (json) => User.fromJson(json),
);
if (response.success) {
print('User created: ${response.data!.id}');
}
PATCH Request
final response = await RestEzClient.instance.patch<User>(
endpoint: '/users/1',
body: {
'name': 'John Smith',
},
fromJson: (json) => User.fromJson(json),
);
DELETE Request
final response = await RestEzClient.instance.delete<void>(
endpoint: '/users/1',
);
if (response.success) {
print('User deleted successfully');
}
Advanced Usage
Custom Error Handling
class MyErrorInterceptor implements ErrorInterceptor {
@override
void handleError(EndpointResponse response) {
// Custom error handling
switch (response.response) {
case ResponseType.unAuthorized:
// Handle unauthorized access
print('User needs to login again');
break;
case ResponseType.internetIssue:
// Handle network issues
print('Check your internet connection');
break;
default:
print('An error occurred: ${response.response}');
}
}
@override
void handleSuccess(EndpointResponse response) {
// Handle successful responses
print('Request successful');
}
}
// Initialize with custom error interceptor
RestEzClient.instance.initialize(
config: const RestEzConfig(baseUrl: 'https://api.example.com'),
errorInterceptor: MyErrorInterceptor(),
);
Custom Endpoints
enum MyApiEndpoint implements ApiEndpoint {
users('/users'),
posts('/posts'),
comments('/comments');
const MyApiEndpoint(this.path);
@override
final String path;
@override
String get name => toString().split('.').last;
}
// Use with requests
final response = await RestEzClient.instance.get<List<User>>(
endpoint: MyApiEndpoint.users.path,
endpointType: MyApiEndpoint.users,
fromJson: (json) => (json as List)
.map((item) => User.fromJson(item))
.toList(),
);
Web File Downloads (Flutter Web only)
// Download a file
await RestEzClient.instance.downloadFileWeb(
endpoint: '/reports/annual-report.pdf',
filename: 'annual_report_2023.pdf',
queryParameters: {'year': '2023'},
);
// Print a PDF
await RestEzClient.instance.printPdf(
endpoint: '/invoices/123/pdf',
queryParameters: {'format': 'A4'},
);
Configuration Options
const config = RestEzConfig(
baseUrl: 'https://api.example.com', // Required: Base URL for all requests
defaultTimeout: Duration(seconds: 30), // Default timeout for requests
defaultHeaders: { // Default headers for all requests
"Content-Type": "application/json",
"Accept": "*/*",
},
enableTokenCheck: true, // Enable automatic token validation
enableLogging: true, // Enable debug logging
);
Response Types
The package provides several response types for better error handling:
ResponseType.success- Request completed successfullyResponseType.internetIssue- Network connectivity problemsResponseType.unAuthorized- Authentication/authorization issuesResponseType.unknownIssue- Unknown errorsResponseType.serverIssue- Server-side errorsResponseType.timeout- Request timeout
Error Handling
The APIResponse<T> class provides a consistent way to handle responses:
final response = await RestEzClient.instance.get<User>(...);
if (response.success) {
// Handle successful response
User user = response.data!;
} else {
// Handle error
print('Error (${response.statusCode}): ${response.error}');
}
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.