minimal_rest_http 1.0.0
minimal_rest_http: ^1.0.0 copied to clipboard
A minimal, dynamic, and configurable REST HTTP client for Flutter applications with built-in error handling, retry logic, and flexible endpoint management.
import 'package:flutter/material.dart';
import 'package:minimal_rest_http/api_service.dart';
import 'comprehensive_usage.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize the API service
await _initializeApiService();
runApp(MyApp());
}
Future<void> _initializeApiService() async {
// Create configuration
final config = ApiConfig(
baseUrl: 'https://jsonplaceholder.typicode.com',
timeoutSeconds: 30,
enableLogging: true,
enableErrorPopups: true,
authTokenKey: 'access_token',
);
// Create auth manager
final authManager = SharedPreferencesAuthManager(
tokenKey: 'access_token',
);
// Create endpoint manager
final endpointManager = EndpointManager(baseUrl: config.baseUrl);
endpointManager.addEndpoints({
'users': '/users',
'posts': '/posts',
'comments': '/comments',
'albums': '/albums',
'photos': '/photos',
'todos': '/todos',
});
// Initialize REST HTTP service
await MinRestService.initialize(
config: config,
authManager: authManager,
endpointManager: endpointManager,
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Minimal REST HTTP Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage().withApiContext(), // Automatic context detection
routes: {
'/comprehensive': (context) => ComprehensiveUsageExample(),
},
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final MinRestService _minRestService = MinRestService.instance;
List<Map<String, dynamic>> _users = [];
bool _loading = false;
String _error = '';
@override
void initState() {
super.initState();
_loadUsers();
}
Future<void> _loadUsers() async {
setState(() {
_loading = true;
_error = '';
});
try {
// Using endpoint manager - response can be any format
final response = await _minRestService.getByKey<dynamic>(
'users',
fromJson: (data) => data, // Pass through as-is
showErrorPopup: true,
);
// Handle any response format
List<dynamic> users;
if (response is List) {
users = response;
} else if (response is Map<String, dynamic>) {
// Check if data is in a 'data' field or similar
users = ResponseUtils.getData(response) as List<dynamic>? ?? [];
} else {
users = [];
}
setState(() {
_users = users.cast<Map<String, dynamic>>();
_loading = false;
});
} catch (e) {
setState(() {
_error = e.toString();
_loading = false;
});
}
}
Future<void> _createPost() async {
try {
final newPost = await _minRestService.postByKey<Map<String, dynamic>>(
'posts',
body: {
'title': 'New Post',
'body': 'This is a new post created with Minimal REST HTTP',
'userId': 1,
},
fromJson: (data) => data as Map<String, dynamic>,
showErrorPopup: true,
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Post created: ${newPost['title']}')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e')),
);
}
}
Future<void> _testAuth() async {
// Set a test token
await _minRestService.setAuthToken('test_token_123');
// Check if token exists
final hasToken = await _minRestService.hasAuthToken();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Has token: $hasToken')),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Minimal REST HTTP Example'),
),
body: _loading
? Center(child: CircularProgressIndicator())
: _error.isNotEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Error: $_error'),
SizedBox(height: 16),
ElevatedButton(
onPressed: _loadUsers,
child: Text('Retry'),
),
],
),
)
: ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
final user = _users[index];
return ListTile(
title: Text(user['name'] ?? 'Unknown'),
subtitle: Text(user['email'] ?? 'No email'),
trailing: Text('ID: ${user['id']}'),
);
},
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _createPost,
child: Icon(Icons.add),
tooltip: 'Create Post',
),
SizedBox(height: 8),
FloatingActionButton(
onPressed: _testAuth,
child: Icon(Icons.security),
tooltip: 'Test Auth',
),
SizedBox(height: 8),
FloatingActionButton(
onPressed: () => Navigator.pushNamed(context, '/comprehensive'),
child: Icon(Icons.code),
tooltip: 'Comprehensive Example',
),
],
),
);
}
}