smart_arch 0.1.0
smart_arch: ^0.1.0 copied to clipboard
Smart Flutter architecture and application infrastructure toolkit with state-agnostic core primitives.
smart_arch #
A state-management-agnostic Flutter architecture and application infrastructure toolkit.
Why smart_arch? #
Flutter applications repeatedly implement the same infrastructure:
- API calls
- JSON parsing
- network errors
- loading/success/failure states
- retries
- logging
- request configuration
smart_arch provides small, composable primitives so application code can stay focused on business logic.
V0.1.0 #
This first release intentionally focuses on the foundation:
SmartResult<T>SmartErrorSmartState<T>SmartApi- GET/POST/PUT/PATCH/DELETE
- Dio integration
- request configuration
- HTTP error mapping
- retry with exponential backoff
- lightweight logging
Future releases can add authentication, token refresh, pagination, search/debounce, caching, storage, connectivity and state-management adapters.
Installation #
Add the package to your application:
dependencies:
smart_arch: ^0.1.0
Then:
flutter pub get
Basic API request #
final api = SmartApi.create(
baseUrl: 'https://api.example.com',
);
final result = await api.get<User>(
'/users/10',
parser: User.fromJson,
);
result.when(
success: (user) {
print(user.name);
},
failure: (error) {
print(error.message);
},
);
POST request #
final result = await api.post<User>(
'/users',
request: SmartRequest(
data: {
'name': 'Amit',
'email': 'amit@example.com',
},
),
parser: User.fromJson,
);
State handling #
SmartState<User> state = const SmartState.initial();
state = const SmartState.loading();
final result = await api.get<User>(
'/users/10',
parser: User.fromJson,
);
state = result.when(
success: SmartState.success,
failure: SmartState.failure,
);
Retry #
final api = SmartApi.create(
baseUrl: 'https://api.example.com',
retryPolicy: const SmartRetryPolicy(
maxAttempts: 3,
delay: Duration(milliseconds: 500),
backoffMultiplier: 2,
),
);
Only retryable failures are retried in V0.1.0: network, timeout and server errors.
Request options #
final result = await api.get<List<User>>(
'/users',
request: SmartRequest(
headers: {
'Authorization': 'Bearer token',
},
queryParameters: {
'page': 1,
'limit': 20,
},
),
parser: (json) {
return (json as List)
.map((item) => User.fromJson(item))
.toList();
},
);
Interceptors #
SmartApi exposes its underlying Dio instance:
api.dio.interceptors.add(
SmartInterceptor(
onRequestStarted: (options) async {
// Add request-level behavior.
},
onResponseReceived: (response) async {
// Observe responses.
},
onErrorReceived: (error) async {
// Observe failures.
},
),
);
Architecture principle #
The core package does not depend on:
- GetX
- Riverpod
- BLoC
- Provider
- Redux
This keeps the package reusable.
Planned adapters:
smart_arch
├── smart_arch_getx
├── smart_arch_riverpod
└── smart_arch_bloc
Recommended project usage #
lib/
├── core/
├── data/
│ ├── models/
│ ├── repositories/
│ └── services/
├── features/
│ └── users/
│ ├── controller/
│ ├── pages/
│ └── widgets/
└── main.dart
smart_arch should provide infrastructure; your application should own business rules.
Development #
flutter pub get
flutter analyze
flutter test
dart format .
Run the example:
cd example
flutter pub get
flutter run
Publishing checklist #
Before publishing:
dart pub publish --dry-run
flutter analyze
flutter test
Then:
dart pub publish
Replace placeholder repository URLs in pubspec.yaml before publishing.
License #
MIT.