A robust, configurable Flutter package that simplifies HTTP networking by wrapping dio with built-in features for authentication, secure storage management, logging, and error tracking.
- Global Configuration: Easily configure base URL, headers, and timeouts for all requests.
- Controller Pattern: Use the
BaseController<T>base class to create organized, maintainable API endpoints with built-in response decoding. - Flexible Status Codes: Define custom success HTTP status codes per endpoint.
- Authentication Management: Built-in support for login, logout, and state management via
AuthManager. - Automatic Token Handling: Interceptors for automatically appending access tokens and handling token refresh workflows.
- Secure Storage: Integrated
flutter_secure_storageto safely store user data, access tokens, and refresh tokens. - Third-Party Integrations: Easily add Sentry error tracking (
sentry_dio) and advanced logging (awesome_dio_interceptor).
Add api_client to your pubspec.yaml dependencies.
dependencies:
api_client: ^0.0.1Initialize the global configuration before making any requests, typically in your main() method:
import'package:api_client/api_client.dart';
import'package:flutter/material.dart';
voidmain() {
// Set your API Base URLConfiguration.baseUrl ='https://api.example.com/v1';
// Optional flag to enable advanced loggingConfiguration.enableLogs =true;
runApp(constMainApp());
}Create clear and type-safe endpoints by extending BaseController<T>:
import'package:api_client/api_client.dart';
baseclassGetUsersControllerextendsBaseController<List<User>> {
GetUsersController()
:super(
path:'/users',
method:HTTPMethod.get,
authenticated:true, // Automatically includes auth headers
successStatusCodes:const [200, 201], // Define custom success status codes
responseDecoder: (data) =>
(data asList).map((e) =>User.fromJson(e)).toList(),
);
}final controller =GetUsersController();final result =await controller.callWithResult();
switch (result) {
caseSuccess(data:final data):// Handle successbreak;
caseFailed(error:final error, stackTrace:final stackTrace, data:final data):// Handle errorbreak;
}final result =await controller.call();
if(result.isEmpty){
// handle empty result
}else{
// handle result
}Use AuthManager to handle login, which automatically extracts and stores the tokens securely.
final authManager =AuthManager.instance;
// Login and save tokensfinal user =await authManager.login(
path:'/auth/login',
data: {
'email':'user@example.com',
'password':'securepassword',
},
decoder: (data) =>UserModel.fromJson(data),
);
// Get current user from secure storagefinal cachedUser =await authManager.me();
// Logout and clear tokensawait authManager.logout(
path:'/auth/logout',
decoder: (data) => data,
);You can listen to authManagerStream to respond to session events (like session expiry) across your app:
AuthManager.instance.authManagerStream.listen((event) {
if (event.type ==AuthManagerEventType.sessionExpired) {
// Navigate to Login Screen
}
});For more examples, please refer to the /example folder in the package repository.
To contribute or report issues, please check the repository's issue tracker.