5.2 KiB
5.2 KiB
API Client Quick Reference
Import
import 'package:minhthu/core/core.dart';
Initialization
final secureStorage = SecureStorage();
final apiClient = ApiClient(
secureStorage,
onUnauthorized: () => context.go('/login'),
);
HTTP Methods
GET Request
final response = await apiClient.get(
'/warehouses',
queryParameters: {'limit': 10},
);
POST Request
final response = await apiClient.post(
'/auth/login',
data: {'username': 'user', 'password': 'pass'},
);
PUT Request
final response = await apiClient.put(
'/products/123',
data: {'name': 'Updated'},
);
DELETE Request
final response = await apiClient.delete('/products/123');
Parse API Response
final apiResponse = ApiResponse.fromJson(
response.data,
(json) => User.fromJson(json), // or your model
);
if (apiResponse.isSuccess && apiResponse.value != null) {
final data = apiResponse.value;
// Use data
} else {
final error = apiResponse.getErrorMessage();
// Handle error
}
Error Handling
try {
final response = await apiClient.get('/products');
} on NetworkException catch (e) {
// Timeout, no internet
print('Network error: ${e.message}');
} on ServerException catch (e) {
// HTTP errors (401, 404, 500, etc.)
print('Server error: ${e.message}');
print('Error code: ${e.code}');
}
Token Management
Save Token
await secureStorage.saveAccessToken('your_token');
await secureStorage.saveRefreshToken('refresh_token');
Get Token
final token = await secureStorage.getAccessToken();
Check Authentication
final isAuthenticated = await apiClient.isAuthenticated();
Clear Tokens (Logout)
await apiClient.clearAuth();
API Endpoints
Use constants from ApiEndpoints:
// Authentication
ApiEndpoints.login // /auth/login
ApiEndpoints.logout // /auth/logout
// Warehouses
ApiEndpoints.warehouses // /warehouses
ApiEndpoints.warehouseById(1) // /warehouses/1
// Products
ApiEndpoints.products // /products
ApiEndpoints.productById(123) // /products/123
// Query parameters helper
ApiEndpoints.productQueryParams(
warehouseId: 1,
type: 'import',
) // {warehouseId: 1, type: 'import'}
Utilities
Test Connection
final isConnected = await apiClient.testConnection();
Update Base URL
apiClient.updateBaseUrl('https://dev-api.example.com');
Get Current Token
final token = await apiClient.getAccessToken();
Common Patterns
Login Flow
// 1. Login
final response = await apiClient.post(
ApiEndpoints.login,
data: {'username': username, 'password': password},
);
// 2. Parse
final apiResponse = ApiResponse.fromJson(
response.data,
(json) => User.fromJson(json),
);
// 3. Save tokens
if (apiResponse.isSuccess && apiResponse.value != null) {
final user = apiResponse.value!;
await secureStorage.saveAccessToken(user.accessToken);
await secureStorage.saveUserId(user.userId);
}
Repository Pattern
class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
final ApiClient apiClient;
WarehouseRemoteDataSourceImpl(this.apiClient);
@override
Future<List<Warehouse>> getWarehouses() async {
final response = await apiClient.get(ApiEndpoints.warehouses);
final apiResponse = ApiResponse.fromJson(
response.data,
(json) => (json as List).map((e) => Warehouse.fromJson(e)).toList(),
);
if (apiResponse.isSuccess && apiResponse.value != null) {
return apiResponse.value!;
} else {
throw ServerException(apiResponse.getErrorMessage());
}
}
}
Configuration
Set Base URL
In lib/core/constants/app_constants.dart:
static const String apiBaseUrl = 'https://api.example.com';
Set Timeouts
In lib/core/constants/app_constants.dart:
static const int connectionTimeout = 30000; // 30 seconds
static const int receiveTimeout = 30000;
static const int sendTimeout = 30000;
Files Location
- API Client:
/lib/core/network/api_client.dart - API Response:
/lib/core/network/api_response.dart - Secure Storage:
/lib/core/storage/secure_storage.dart - API Endpoints:
/lib/core/constants/api_endpoints.dart - Examples:
/lib/core/network/api_client_example.dart - Documentation:
/lib/core/network/README.md
Important Notes
- Automatic Token Injection: Bearer token is automatically added to all requests
- 401 Handling: 401 errors automatically clear tokens and trigger
onUnauthorizedcallback - Logging: All requests/responses are logged with sensitive data redacted
- Singleton Storage: SecureStorage is a singleton - use
SecureStorage()everywhere - Error Codes: ServerException includes error codes (e.g., '401', '404', '500')
Common Issues
Token not injected?
Check if token exists: await secureStorage.getAccessToken()
401 not clearing tokens?
Verify onUnauthorized callback is set in ApiClient constructor
Connection timeout?
Check network, verify base URL, increase timeout in constants
Logs not showing?
Check Flutter DevTools console or developer.log output