AnyNet π
- Unified Networking for Flutter (DEV Preview)
- Version: 0.1.0-dev.1
- Status: Experimental / Developer Preview
β¨ What is AnyNet?
- AnyNet is an experimental networking layer for Flutter that provides a clean, unified API inspired by http and dio, with built-in features that apps usually re-implement again and again.
- It is designed to replace direct usage of http / dio in application code, while remaining flexible and adapter-driven internally.
β οΈ This is a DEV release. APIs may change based on feedback.
π― Why AnyNet?
- Using http or dio directly often leads to:
- Repeated boilerplate
- Inconsistent error handling
- Manual retry logic
- Scattered logging
- Custom caching everywhere
- AnyNet solves this by design.
β Features (v0.1.0-dev.1)
- Core Networking
get / post / put / delete helpers- Base URL support
- JSON β Object mapping
- Unified ApiResponse
- Unified ApiError
- Reliability
- Automatic retry with exponential backoff
- Timeout handling
- Connectivity-aware requests
- Cancelable requests
Architecture
- Interceptor system (like Dio)
- Logging interceptor (built-in)
- Pluggable adapters (IO-based for now)
Caching
- In-memory request caching
- Cache-aware GET requests
β Whatβs NOT included (yet)
- Persistent cache (disk)
- Multipart uploads
- Auth refresh handling
Web adapter
- Advanced Dio parity
- These will arrive after feedback.
π¦ Installation
- dependencies:
anynet: ^0.1.0-dev.1
π Quick Start
1οΈβ£ Create a client
final client = AnyNetClient(
baseUrl: 'https://jsonplaceholder.typicode.com',
retryPolicy: const RetryPolicy(maxRetries: 2),
cache: MemoryCache(),
interceptors: [LoggingInterceptor()],
);
2οΈβ£ GET request
final response = await client.get<User>(
'/users/1',
mapper: (json) => User.fromJson(json),
);
if (response.isSuccess) {
print(response.data);
}
3οΈβ£ POST request
final response = await client.post<User>(
'/users',
body: {
'name': 'AnyNet User',
'email': 'anynet@example.com',
},
mapper: (json) => User.fromJson(json),
);
4οΈβ£ PUT / DELETE
await client.put(
'/users/1',
body: {'name': 'Updated Name'},
);
await client.delete('/users/1');
π Unified Response Model
class ApiResponse<T> {
final T? data;
final ApiError? error;
final int? statusCode;
bool get isSuccess => error == null;
}
β Unified Error Handling
switch (response.error?.type) {
case ApiErrorType.offline:
print('No internet');
case ApiErrorType.timeout:
print('Request timed out');
case ApiErrorType.network:
print('Network error');
default:
print('Unknown error');
}
π§© Interceptors
-
Create interceptors just like Dio:
class LoggingInterceptor extends AnyNetInterceptor { @override Future<ApiRequest> onRequest(ApiRequest request) async { print('β ${request.method} ${request.url}'); return request; } @override Future<ApiResponse> onResponse(ApiResponse response) async { print('β ${response.statusCode}'); return response; } @override Future<ApiError> onError(ApiError error) async { print('β ${error.message}'); return error; } }
π§ͺ Example App
- A full example is available in /example showing:
- GET list (ListView)
- POST / PUT / DELETE
- Retry & backoff
Logging
- Offline simulation
- Error β UI mapping
π§ Design Philosophy
- Simple for beginners
- Powerful for advanced users
- Minimal boilerplate
- Predictable behavior
- AnyNet is not about hiding networking β itβs about standardizing it.
π£ Roadmap
- Dio adapter
- Persistent cache
- Auth interceptors
- Multipart uploads
- Web support
- Metrics & tracing
π€ Contributing
- This is an early DEV release β feedback is extremely valuable.
- Issues
- Feature requests
- API suggestions
- All welcome π