api_caller 2.0.1
api_caller: ^2.0.1 copied to clipboard
A flexible API helper built on Dio with support for singleton usage, dynamic base URL override, per-request bearer token, JSON & FormData requests, and typed responses.
π¦ ApiHelper (Dio Based API Manager)
A singleton-based, reusable API helper built on top of Dio, supporting:
β Global base URL & token
β Per-API override (base URL + token)
β GET / POST / PUT / DELETE / PATCH
β JSON, www-form-urlencoded, multipart/form-data
β Safe cloning (no data leak between APIs)
β Clean & scalable architecture
π Features
One-time initialization
Dynamic bearer token update
Override base URL & token for only one API
Supports:
JSON body
www-form-urlencoded
multipart/form-data (file upload)
Centralized response handling
π Structure lib/ ββ api_caller.dart ββ models/ β ββ api_caller_path_item.dart β ββ api_caller_request_type.dart
π§ Initialization (ONE TIME) ApiHelper.instance.init( baseUrl: "https://api.example.com", token: "GLOBAL_TOKEN_123", paths: [ ApiHelperPathItem.get("getUsers", "/users"), ApiHelperPathItem.post("addUser", "/users/add"), ApiHelperPathItem.post("uploadFile", "/upload"), ], );
β This sets global base URL & token β Can be used anywhere in app
π₯ GET Request (Normal) final res = await ApiHelper.instance.get("getUsers");
if (res.isSuccess) { print(res.value); } else { print(res.errorMessage); }
β‘ Uses global base URL + global token
π€ POST JSON Data final res = await ApiHelper.instance.post( "addUser", data: { "name": "Bittu", "email": "bittu@example.com", }, contentType: Headers.jsonContentType, );
π€ POST www-form-urlencoded final res = await ApiHelper.instance.post( "addUser", data: { "username": "demo_user", "password": "123456", }, contentType: Headers.formUrlEncodedContentType, );
π€ POST multipart / Form-Data (File Upload) final formData = FormData.fromMap({ "title": "Profile Pic", "file": MultipartFile.fromBytes( [1, 2, 3, 4], filename: "image.png", ), });
final res = await ApiHelper.instance.post( "uploadFile", data: formData, contentType: Headers.multipartFormDataContentType, );
π Change Token Dynamically (Global) ApiHelper.instance.setToken("NEW_GLOBAL_TOKEN");
β‘ All APIs will now use the new token
π Override Base URL & Token (ONLY ONE API) final item = ApiHelper.instance.getPathItem("getUsers") ..setBaseUrlOverride("https://uat.example.com") ..setTokenOverride("UAT_ONLY_TOKEN");
final res = await ApiHelper.instance.request(item);
β Override applies only to this request β Other APIs remain unchanged
π Back to Normal Automatically final res = await ApiHelper.instance.get("getUsers");
β‘ Uses original global base URL & token again
π§ Token Priority Order Request Token (highest) β Path Override Token β Global Token (lowest)
π§ Base URL Priority Path Override Base URL β Global Base URL
β Error Handling if (!res.isSuccess) { print(res.errorMessage); }
Handled cases:
Network error
Timeout
4xx / 5xx status codes
Dio exceptions
β Best Practices
β Call init() only once β Always use getPathItem() for overrides β Never modify stored path directly β Prefer override instead of new instance
π Conclusion
This ApiHelper provides a clean, scalable, and production-ready way to manage APIs in Flutter with:
Minimal boilerplate
Maximum flexibility
Safe override mechanism
If you want, I can also provide:
π¦ Flutter UI integration example
π Token refresh interceptor
π§ͺ Unit tests
π§© Repository-pattern wrapper
