autopilot_api 1.0.0
autopilot_api: ^1.0.0 copied to clipboard
Zero-boilerplate smart API engine for Flutter. Only uses http + shared_preferences.
๐ AutoPilot API #
Zero-boilerplate smart API engine for Flutter. Only uses
http+shared_preferences. No Dio. No extra deps.
๐ฏ What it Solves #
Stop writing 40+ lines per endpoint. AutoPilot does it all:
// โ Before โ boilerplate everywhere
Future<UserModel?> getUser() async {
try {
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString('token');
final res = await http.get(
Uri.parse('$baseUrl/users/1'),
headers: {'Authorization': 'Bearer $token', 'Content-Type': 'application/json'},
).timeout(const Duration(seconds: 30));
if (res.statusCode == 200) {
final json = jsonDecode(res.body);
if (json['status'] == true) return UserModel.fromJson(json['data']);
}
} on SocketException { ... } on TimeoutException { ... } catch (e) { ... }
return null;
}
// โ
After โ just this
final res = await api.get(endpoint: "/users/1", parser: UserModel.fromJson);
if (res.isSuccess) print(res.data);
๐ฆ Installation #
dependencies:
autopilot_api: ^1.0.0
โก Setup #
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AutoPilotApi.init(
baseUrl : "https://api.example.com/v1",
enableLogs : true,
printPayload : true, // full JSON in debug console
enableCache : true,
maxRetries : 3,
enableGlobalLoader : true,
onLoadingChanged : (v) => AppController.setLoading(v),
onError : (msg, code) => showSnackbar(msg),
enableTokenRefresh : true,
onRefreshToken : () async => AuthService.refresh(),
);
runApp(const MyApp());
}
๐ All Requests #
final api = AutoPilotApi.instance;
// GET single
await api.get(endpoint: "/users/1", parser: UserModel.fromJson);
// GET list
await api.get<List<UserModel>>(
endpoint : "/users",
parser : (j) => (j as List).map(UserModel.fromJson).toList(),
useCache : true,
);
// GET with query params
await api.get(
endpoint : "/posts",
queryParams : {"userId": 1, "page": 2},
);
// POST
await api.post(
endpoint : "/login",
body : {"email": email, "password": password},
parser : LoginModel.fromJson,
);
// PUT / PATCH / DELETE
await api.put(endpoint: "/posts/1", body: {"title": "Updated"});
await api.patch(endpoint: "/users/1", body: {"name": "New"});
await api.delete(endpoint: "/posts/1");
// MULTIPART โ single file
await api.multipart(
endpoint : "/upload",
fileKey : "image",
filePath : file.path,
);
// MULTIPART โ multiple files + fields
await api.multipart(
endpoint : "/gallery",
files : [
MultipartFileModel(key: "photos", path: p1),
MultipartFileModel(key: "photos", path: p2),
],
fields : {"album": "vacation"},
onProgress : (sent, total) => print('${(sent/total*100).toInt()}%'),
);
// DOWNLOAD
await api.download(
endpoint : "/report.pdf",
savePath : "/storage/report.pdf",
onProgress : (recv, total) => print('$recv/$total'),
);
๐ฆ ApiResponse<T> #
res.isSuccess // bool
res.data // T? โ parsed model
res.message // success/error message
res.statusCode // 200, 404, 500...
res.raw // raw JSON
res.errors // validation errors map
res.requestId // tracing ID
res.responseTime // Duration
res.isUnauthorized // statusCode == 401
res.isValidationError // statusCode == 422
res.validationError('email') // first error for field
res.allErrors // all errors as string
res.dataOr(fallback) // safe access with fallback
๐ Token #
await AutoPilotApi.setToken(token); // set
await AutoPilotApi.setTokens(accessToken: a, refreshToken: r);
await AutoPilotApi.clearTokens(); // logout
๐พ Cache #
// Global
await AutoPilotApi.init(enableCache: true, cacheDuration: Duration(minutes: 5));
// Per-request
await api.get(endpoint: "/config", useCache: true, cacheDuration: Duration(hours: 1));
// Invalidate
await api.invalidateCache("/config");
await api.clearCache();
๐ฃ Extensions #
// .handle() โ clean success/failure
await api.get(endpoint: "/me", parser: UserModel.fromJson).handle(
onSuccess : (data, msg) => setState(() => user = data),
onFailure : (msg, code) => showSnackbar(msg),
);
// .mapData() โ transform data type
final res = await api.get<String>(endpoint: "/count")
.mapData((s) => int.parse(s));
๐ Environment Switch #
api.reconfigure((c) => c.copyWith(baseUrl: "https://staging.api.com"));
๐งช Tests #
flutter test
๐ License #
MIT