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>
  • SmartError
  • SmartState<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
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.

Libraries

smart_arch
A state-management-agnostic Flutter architecture and application infrastructure toolkit.