http_nexus 1.0.0
http_nexus: ^1.0.0 copied to clipboard
A lightweight but powerful HTTP client wrapper that simplifies API handling with automatic retries, error management, and network failure handling.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:http_nexus/http_nexus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Smart API Client Example',
theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
home: const ApiExamplePage(),
);
}
}
class ApiExamplePage extends StatefulWidget {
const ApiExamplePage({super.key});
@override
State<ApiExamplePage> createState() => _ApiExamplePageState();
}
class _ApiExamplePageState extends State<ApiExamplePage> {
late final SmartApiClient _apiClient;
String _responseText = '';
bool _isLoading = false;
@override
void initState() {
super.initState();
_initializeApiClient();
}
void _initializeApiClient() {
// Configure the API client
final config = ApiClientConfig(
baseUrl: 'https://jsonplaceholder.typicode.com',
defaultTimeout: const Duration(seconds: 10),
retryPolicy: const RetryPolicy(
maxRetries: 3,
initialDelay: Duration(seconds: 1),
backoffMultiplier: 2.0,
),
enableLogging: true,
);
_apiClient = SmartApiClient(config: config);
// Add logging interceptor
_apiClient.addRequestInterceptor(LoggingInterceptor());
}
Future<void> _performGetRequest() async {
setState(() {
_isLoading = true;
_responseText = 'Loading...';
});
try {
final response = await _apiClient.get('/posts/1');
setState(() {
_responseText = 'GET Request Success!\n\n'
'Title: ${response['title']}\n\n'
'Body: ${response['body']}';
_isLoading = false;
});
} on ApiException catch (e) {
setState(() {
_responseText = 'Error: ${e.toString()}';
_isLoading = false;
});
}
}
Future<void> _performPostRequest() async {
setState(() {
_isLoading = true;
_responseText = 'Loading...';
});
try {
final response = await _apiClient.post(
'/posts',
body: {
'title': 'Smart API Client Test',
'body': 'This is a test post from the example app',
'userId': 1,
},
);
setState(() {
_responseText = 'POST Request Success!\n\n'
'Created Post ID: ${response['id']}\n'
'Title: ${response['title']}\n'
'Body: ${response['body']}';
_isLoading = false;
});
} on ApiException catch (e) {
setState(() {
_responseText = 'Error: ${e.toString()}';
_isLoading = false;
});
}
}
Future<void> _testRetryLogic() async {
setState(() {
_isLoading = true;
_responseText = 'Testing retry logic with invalid endpoint...';
});
try {
// This will fail and demonstrate retry logic
await _apiClient.get('/invalid-endpoint-that-does-not-exist');
setState(() {
_responseText = 'Unexpected success!';
_isLoading = false;
});
} on ApiException catch (e) {
setState(() {
_responseText = 'Retry Logic Test:\n\n'
'Request failed after retries as expected.\n\n'
'Error: ${e.toString()}';
_isLoading = false;
});
}
}
Future<void> _testErrorHandling() async {
setState(() {
_isLoading = true;
_responseText = 'Testing error handling...';
});
try {
// Request a non-existent resource
await _apiClient.get('/posts/9999999');
setState(() {
_responseText = 'Unexpected response';
_isLoading = false;
});
} on ServerException catch (e) {
setState(() {
_responseText = 'Error Handling Test:\n\n'
'Caught ServerException as expected!\n\n'
'Status Code: ${e.statusCode}\n'
'Message: ${e.message}';
_isLoading = false;
});
} on ApiException catch (e) {
setState(() {
_responseText = 'Error: ${e.toString()}';
_isLoading = false;
});
}
}
@override
void dispose() {
_apiClient.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Smart API Client Example'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'Smart API Client Features Demo',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
const SizedBox(height: 20),
ElevatedButton.icon(
onPressed: _isLoading ? null : _performGetRequest,
icon: const Icon(Icons.download),
label: const Text('Test GET Request'),
),
const SizedBox(height: 10),
ElevatedButton.icon(
onPressed: _isLoading ? null : _performPostRequest,
icon: const Icon(Icons.upload),
label: const Text('Test POST Request'),
),
const SizedBox(height: 10),
ElevatedButton.icon(
onPressed: _isLoading ? null : _testRetryLogic,
icon: const Icon(Icons.refresh),
label: const Text('Test Retry Logic'),
),
const SizedBox(height: 10),
ElevatedButton.icon(
onPressed: _isLoading ? null : _testErrorHandling,
icon: const Icon(Icons.error_outline),
label: const Text('Test Error Handling'),
),
const SizedBox(height: 20),
const Divider(),
const SizedBox(height: 10),
const Text(
'Response:',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Expanded(
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey[300]!),
),
child: SingleChildScrollView(
child: Text(
_responseText.isEmpty ? 'No response yet' : _responseText,
style: const TextStyle(fontSize: 14),
),
),
),
),
],
),
),
);
}
}