quickapi 2.0.0
quickapi: ^2.0.0 copied to clipboard
A modern, feature-rich Flutter HTTP client with caching, retries, interceptors, and advanced error handling
example/example.dart
// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, library_private_types_in_public_api
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:quickapi/quickapi.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QuickApi Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: ApiTestPage(),
);
}
}
class ApiTestPage extends StatefulWidget {
@override
_ApiTestPageState createState() => _ApiTestPageState();
}
class _ApiTestPageState extends State<ApiTestPage> {
late QuickApi _api;
String _response = '';
@override
void initState() {
super.initState();
// Using the new builder pattern with enhanced features
_api = QuickApi.builder()
.baseUrl('https://jsonplaceholder.typicode.com')
.timeout(Duration(seconds: 15))
.retry(3, delay: Duration(seconds: 1), useExponentialBackoff: true)
.cache(Duration(minutes: 5), maxSize: 100)
.addInterceptor(LoggingInterceptor())
.logger((level, message) => log('[QuickApi $level] $message'))
.build();
}
void _testGet() async {
setState(() {
_response = 'Loading...';
});
try {
final result = await _api.get('/posts/1');
setState(() {
_response = 'GET Response: ${result.toString()}';
});
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
void _testPost() async {
setState(() {
_response = 'Loading...';
});
// Define the parameters in a variable
final params = {
'title': 'New Post testing',
'body': 'This is a new post.',
'userId': 1,
};
try {
// Pass the params variable to the API call
final result = await _api.post('/posts', params);
setState(() {
_response = 'POST Response: ${result.toString()}';
});
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
void _testPut() async {
setState(() {
_response = 'Loading...';
});
try {
final result = await _api.put('/posts/1', {
'title': 'Updated Post',
'body': 'This is an updated post.',
'userId': 1,
});
setState(() {
_response = 'PUT Response: ${result.toString()}';
});
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
void _testDelete() async {
setState(() {
_response = 'Loading...';
});
try {
final result = await _api.delete('/posts/1');
setState(() {
_response = 'DELETE Response: ${result.toString()}';
});
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
void _testMultipartPost() async {
setState(() {
_response = 'Loading...';
});
try {
final file = await _pickFile(); // Implement file picker
if (file != null) {
final result = await _api.postMultipart('/upload', {
'description': 'Test File Upload'
}, [
http.MultipartFile.fromBytes('file', await file.readAsBytes(),
filename: 'file.jpg')
]);
setState(() {
_response = 'Multipart POST Response: ${result.toString()}';
});
} else {
setState(() {
_response = 'No file selected';
});
}
} catch (e) {
setState(() {
_response = 'Error: $e';
});
}
}
void _testRetryMechanism() async {
setState(() {
_response = 'Testing retry mechanism...';
});
try {
// This endpoint will fail and trigger retries
final result = await _api.get('/nonexistent-endpoint');
setState(() {
_response = 'Unexpected success: ${result.toString()}';
});
} catch (e) {
setState(() {
_response = 'Expected error after retries: $e';
});
}
}
void _testCache() async {
setState(() {
_response = 'Testing cache...';
});
try {
// First request - should hit the network
final startTime = DateTime.now();
await _api.get('/posts/1');
final firstRequestTime = DateTime.now().difference(startTime);
// Second request - should hit the cache
final cacheStartTime = DateTime.now();
await _api.get('/posts/1');
final cacheRequestTime = DateTime.now().difference(cacheStartTime);
setState(() {
_response = 'Cache Test Results:\n'
'First request: ${firstRequestTime.inMilliseconds}ms\n'
'Cached request: ${cacheRequestTime.inMilliseconds}ms\n'
'Cache speedup: ${(firstRequestTime.inMilliseconds / cacheRequestTime.inMilliseconds).toStringAsFixed(1)}x';
});
} catch (e) {
setState(() {
_response = 'Cache test error: $e';
});
}
}
Future<File?> _pickFile() async {
// Implement file picker logic here (using file_picker package)
return null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QuickApi Test - Enhanced Features'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Enhanced QuickApi Features Demo',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
Wrap(
spacing: 10,
runSpacing: 10,
children: [
ElevatedButton(
onPressed: _testGet,
child: Text('Test GET'),
),
ElevatedButton(
onPressed: _testPost,
child: Text('Test POST'),
),
ElevatedButton(
onPressed: _testPut,
child: Text('Test PUT'),
),
ElevatedButton(
onPressed: _testDelete,
child: Text('Test DELETE'),
),
ElevatedButton(
onPressed: _testMultipartPost,
child: Text('Test File Upload'),
),
ElevatedButton(
onPressed: _testRetryMechanism,
child: Text('Test Retry'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
),
),
ElevatedButton(
onPressed: _testCache,
child: Text('Test Cache'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
),
),
],
),
SizedBox(height: 20),
Text('Response:',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(height: 10),
Container(
width: double.infinity,
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey[300]!),
),
child: Text(
_response,
style: TextStyle(fontSize: 14, fontFamily: 'monospace'),
),
),
SizedBox(height: 20),
Text(
'Features Demonstrated:',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Text('• Builder pattern for easy configuration\n'
'• Automatic retry mechanism (3 attempts)\n'
'• Built-in logging interceptor\n'
'• Response caching (5 minutes)\n'
'• Network connectivity checks\n'
'• Enhanced error handling\n'
'• Timeout management (15 seconds)'),
],
),
),
);
}
}