CallKitNet
A powerful, developer-friendly networking package built on top of Dio for Flutter and Dart applications.
CallKitNet simplifies API integration by providing authentication, automatic logging, retry mechanisms, refresh token support, model parsing, file uploads/downloads, request cancellation, and centralized error handling — all with a clean and type-safe API.
✨ Features
- 🚀 Built on top of Dio
- 📝 Automatic Request Logging
- ✅ Automatic Response Logging
- ❌ Automatic Error Logging
- 📋 Automatic cURL Generation
- 🔐 Authentication Support
- 🔄 Refresh Token Support
- 🔁 Automatic Retry Mechanism
- 📦 Generic Model Parsing
- 🛡 Safe Result API
- 📤 File Upload Support
- 📈 Upload Progress Tracking
- 📥 File Download Support
- 📊 Download Progress Tracking
- ⛔ Request Cancellation
- ⚠️ Centralized Error Handling
- 🎯 Type-Safe API Calls
- 📱 Flutter & Dart Compatible
Installation
Add the package to your pubspec.yaml:
dependencies:
callkitnet: ^1.0.0
Install dependencies:
flutter pub get
Import the package:
import 'package:callkitnet/callkitnet.dart';
Quick Start
Create an API client:
final api = CallKitClient(
config: const CallKitConfig(
baseUrl: 'https://api.example.com',
),
);
Create a 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'],
);
}
}
GET Request
Fetch a single object and parse it into a model.
final user = await api.get<User>(
path: '/users/1',
fromJson: User.fromJson,
);
print(user.name);
GET Raw JSON
If fromJson is not provided, CallKitNet returns raw JSON.
final response = await api.get(
path: '/users/1',
);
print(response);
GET List Request
Fetch and parse a list of objects.
final users = await api.getList<User>(
path: '/users',
fromJson: User.fromJson,
);
for (final user in users) {
print(user.name);
}
POST Request
await api.post(
path: '/login',
body: {
'email': 'test@gmail.com',
'password': '123456',
},
);
PUT Request
await api.put(
path: '/users/1',
body: {
'name': 'Sanket',
},
);
PATCH Request
await api.patch(
path: '/users/1',
body: {
'name': 'Updated Name',
},
);
DELETE Request
await api.delete(
path: '/users/1',
);
Authentication
Save an access token:
api.saveToken(
'your_access_token',
);
Every request automatically includes:
Authorization: Bearer your_access_token
Clear the token:
api.clearToken();
Refresh Token Support
Automatically refresh expired tokens and retry failed requests.
final api = CallKitClient(
config: const CallKitConfig(
baseUrl: 'https://api.example.com',
),
refreshTokenHandler: RefreshTokenHandler(
callback: () async {
return await authRepository.refreshToken();
},
),
);
When the server returns:
401 Unauthorized
CallKitNet automatically:
- Refreshes the token
- Saves the new token
- Retries the original request
Safe Result API
Avoid repetitive try-catch blocks.
final result = await api.safeGet<User>(
path: '/profile',
fromJson: User.fromJson,
);
result.when(
success: (user) {
print(user.name);
},
failure: (message, statusCode) {
print(message);
},
);
File Upload
Upload a single file:
await api.upload.uploadFile(
path: '/upload',
file: imageFile,
);
Upload multiple files:
await api.upload.uploadFiles(
path: '/upload',
files: [
image1,
image2,
image3,
],
);
Track upload progress:
await api.upload.uploadFile(
path: '/upload',
file: imageFile,
onProgress: (
sent,
total,
) {
final progress =
(sent / total) * 100;
print(
'Upload: ${progress.toStringAsFixed(0)}%',
);
},
);
File Download
Download a file:
await api.download.download(
url: fileUrl,
savePath: savePath,
);
Track download progress:
await api.download.download(
url: fileUrl,
savePath: savePath,
onProgress: (
received,
total,
) {
final progress =
(received / total) * 100;
print(
'Download: ${progress.toStringAsFixed(0)}%',
);
},
);
Request Cancellation
Create a cancellation token:
final token =
RequestCanceller.create(
'users',
);
Attach the token:
await api.dio.get(
'/users',
cancelToken: token,
);
Cancel the request:
RequestCanceller.cancel(
'users',
);
Error Handling
All network exceptions are converted into CallKitException.
try {
final user = await api.get<User>(
path: '/profile',
fromJson: User.fromJson,
);
} on CallKitException catch (e) {
print(e.message);
print(e.statusCode);
}
Logging
CallKitNet automatically logs:
- 🚀 Requests
- ✅ Responses
- ❌ Errors
- 📋 cURL Commands
Example output:
🚀 REQUEST
GET https://api.example.com/users
📋 CURL
curl -X GET https://api.example.com/users
✅ RESPONSE
200 OK
❌ ERROR
404 Not Found
Enable logging:
final api = CallKitClient(
config: const CallKitConfig(
baseUrl: 'https://api.example.com',
),
options: const CallKitOptions(
enableLogs: true,
printCurl: true,
),
);
Retry Requests
Automatically retry failed requests.
final api = CallKitClient(
config: const CallKitConfig(
baseUrl: 'https://api.example.com',
),
options: const CallKitOptions(
enableRetry: true,
retryCount: 3,
),
);
Roadmap
Version 1.1
- Persistent Token Storage
- Local Cache Layer
- Pagination Helpers
- Request Transformers
- Response Transformers
- API Inspector UI
Version 1.2
- Offline First Support
- Request Queue
- Background Sync
- GraphQL Support
Author
Sanket C Panchal
Flutter Developer
License
MIT License
Copyright (c) 2026 Sanket C Panchal