quickapi 2.0.0 copy "quickapi: ^2.0.0" to clipboard
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)'),
          ],
        ),
      ),
    );
  }
}
4
likes
140
points
14
downloads

Publisher

verified publishertechweblabs.com

Weekly Downloads

A modern, feature-rich Flutter HTTP client with caching, retries, interceptors, and advanced error handling

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

connectivity_plus, flutter, http

More

Packages that depend on quickapi