smart_api 1.0.0 copy "smart_api: ^1.0.0" to clipboard
smart_api: ^1.0.0 copied to clipboard

Dynamic Dio wrapper for Flutter — auto raw/multipart detection, global loader/snackbar hooks, configurable session-expiry & error handling, no-internet retry, and one-line API calls (no repeated try/c [...]

smart_api #

Tera purana BaseClient + ApiProvider pattern kaam karda si, par har naye project ch same 15-line try/catch dobara likhna painda si. Eh package ohi logic ek baar likh ke, sab projects ch reusable bana denda.

Solves #

  • Raw vs multipart confusion — tu ik plain Map bhejda hain; agar usch koi File ya valid local path hai, package khud FormData bana ke MultipartFile convert kar denda. Http url string ho ya normal text ho, ohi raw JSON ban ke jaandi hai. User nu kaddi manually convert nai karna.
  • Loader / snackbar / toast — sab dynamic — koi bhi UI package (GetX, Fluttertoast, custom widget) hard-coded nahi. SmartApiHooks ch ek baar function set karo, har call automatically use karu.
  • Status codes handled centrally — 401/403 (session expire), timeout, connection error, generic server error — sab ik jagah handle, tenu har API ch dobara nahi likhna.
  • No-internet retry — onNoInternet(retry) hook nu retry callback milda hai, tera No-Internet page bas retry() call kare, same request dobara fire ho jaandi.
  • One line per call — SmartApiClient.instance.post(...) — na ApiRequest, na RequestType, na manual DataResponse.fromJson try/catch.

Setup (once, in main.dart) #

SmartApiConfig.init(
  baseUrl: "https://api.example.com",
  headerBuilder: () => {"Authorization": "Bearer ${token}"},
);

SmartApiHooks.showLoader = Utils.showLoading;
SmartApiHooks.hideLoader = Utils.hideLoading;
SmartApiHooks.showMessage = (msg, {type}) => Utils.showAlert(message: msg);
SmartApiHooks.onSessionExpired = () => Get.offAllNamed(AppRoutes.signIn);
SmartApiHooks.onNoInternet = (retry) => Get.to(() => NoInternetPage(onRetry: retry));

Call an API #

final res = await SmartApiClient.instance.post<UserModel>(
  "/api/login",
  body: {"email": email, "password": password},
  fromJson: (json) => UserModel.fromJson(json),
);

if (res.success) {
  // res.data is already a UserModel
} else {
  Utils.showAlert(message: res.message);
}

File upload — no separate handleMultipartRequest needed:

await SmartApiClient.instance.put("/api/editProfile", body: {
  "name": name,
  "image": pickedImage.path, // auto-detected, converted to multipart
});

See example/usage_example.dart for a full before/after against your existing signupApi / editProfile flow.

Backend response shape differs per project? #

Two levels of control:

1. Just rename keys (most cases) — no parser function needed:

SmartApiConfig.init(
  baseUrl: "...",
  keyMap: const SmartApiKeyMap(
    successKeys: ['ok'],
    successValues: [true],
    messageKeys: ['msg'],
    dataKeys: ['payload'],
  ),
);

2. Fully custom shape (nested envelopes, etc.) — write the parser yourself:

SmartApiConfig.init(
  baseUrl: "...",
  responseParser: (json) => SmartApiEnvelope(
    success: json['meta']['ok'] == true,
    message: json['meta']['msg'] ?? '',
    data: json['payload'],
  ),
);

File uploads — auto or explicit, single or multiple, your key names #

By default (autoDetectFiles: true) any File or valid local path inside body is auto-converted to multipart. Turn it off globally or per-request if you'd rather always be explicit:

// Single image, you name the field:
files: [SmartApiFile.single(key: "image", path: path)]

// Multiple images under the same field:
files: SmartApiFile.list(key: "images", paths: [p1, p2, p3])

// Different keys per file (front/back license + selfie):
files: [
  SmartApiFile.single(key: "license_front", path: frontPath),
  SmartApiFile.single(key: "license_back", path: backPath),
  SmartApiFile.single(key: "profile_image", path: selfiePath),
]

files always forces multipart, regardless of autoDetectFiles. Any normal text fields still go in body alongside it.

Query params on any method, not just GET #

SmartApiClient.instance.post(
  "/api/roomSearch",
  body: data,                 // JSON/multipart body
  queryParams: {"id": roomId} // ?id=... appended regardless of method
);

Ideas to extend later #

  • Add a retryCount on SmartApiRequest for auto-retry on 5xx.
  • Add response caching (per-endpoint TTL) for list APIs.
  • Add a downloadFile() helper with progress callback, same hook pattern.
9
likes
0
points
581
downloads

Publisher

unverified uploader

Weekly Downloads

Dynamic Dio wrapper for Flutter — auto raw/multipart detection, global loader/snackbar hooks, configurable session-expiry & error handling, no-internet retry, and one-line API calls (no repeated try/catch boilerplate).

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

dio, flutter

More

Packages that depend on smart_api