Skip to content

Instantly share code, notes, and snippets.

@diefferson
Last active January 24, 2024 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diefferson/17660dcb30233b0c28623a18f67b8eec to your computer and use it in GitHub Desktop.
Save diefferson/17660dcb30233b0c28623a18f67b8eec to your computer and use it in GitHub Desktop.
Flutter API integration
import 'dart:io';
import 'dart:typed_data';
import 'package:base/base.dart';
import 'package:module_account/module_account.dart';
import 'package:module_banking/module_banking.dart';
class AccountApiV1 implements AccountApi {
AccountApiV1(
this._appRest
);
final AppRest _appRest;
@override
Future<void> requestBankingAccount() async {
await _appRest.post(
'/v1/path-to-request-account',
);
}
@override
Future<UserLimits> getUserLimits() async {
final response = await _appRest.get('/v1/path-to-user-limits');
return UserLimits.mapper(response);
}
@override
Future<UserLimits> requestUserLimits({
double? requestedDailyLimit,
double? requestedNightlyLimit,
}) async {
final response = await _appRest.post(
'/v1/path-to-user-limits',
data: {
"requestedDailyLimit": requestedDailyLimit,
"requestedNightlyLimit": requestedNightlyLimit,
}..removeWhere((key, value) => value == null),
);
return UserLimits.mapper(response);
}
}
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:flutter/services.dart';
import 'package:noodle_commons/src/domain/exception/error_handler.dart';
import 'package:noodle_commons/src/utils/json_utils.dart';
import 'package:uuid/uuid.dart';
import 'dio/dio_client.dart';
class AppRest {
final Dio _dio;
final ErrorHandler? _errorHandler;
AppRest(
String baseUrl, {
CacheOptions? cacheOptions,
ErrorHandler? errorHandler,
List<Interceptor>? interceptors,
}) : _errorHandler = errorHandler,
_dio = DioClient.getClient(
baseUrl: baseUrl,
cacheOptions: cacheOptions,
interceptors: interceptors ?? [],
);
static String getCacheKeyBuilder(RequestOptions request, {String name = ''}) {
return const Uuid().v5(Uuid.NAMESPACE_URL,
'${request.uri.toString()}/$name/${request.headers.getString(HttpHeaders.authorizationHeader)}');
}
Future<T> get<T>(
String path, {
Map<String, dynamic>? queryParameters,
Options? options,
bool mock = false,
String? mockAsset,
}) async {
if (mock) {
return await mockResponse(mockAsset);
}
try {
final response = await _dio.get(
path,
queryParameters: queryParameters,
options: options,
);
return response.data;
} catch (exception) {
final e = _errorHandler?.handle(exception);
if (e != null) {
throw e;
} else {
rethrow;
}
}
}
Future<T> post<T>(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
bool mock = false,
String? mockAsset,
}) async {
if (mock) {
return await mockResponse(mockAsset);
}
try {
final response = await _dio.post(
path,
data: data,
queryParameters: queryParameters,
options: options,
);
return response.data;
} catch (exception) {
final e = _errorHandler?.handle(exception);
if (e != null) {
throw e;
} else {
rethrow;
}
}
}
Future<T> put<T>(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
bool mock = false,
String? mockAsset,
}) async {
if (mock) {
return await mockResponse(mockAsset);
}
try {
final response = await _dio.put(
path,
data: data,
queryParameters: queryParameters,
options: options,
);
return response.data;
} catch (exception) {
final e = _errorHandler?.handle(exception);
if (e != null) {
throw e;
} else {
rethrow;
}
}
}
Future<T> delete<T>(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
bool mock = false,
String? mockAsset,
}) async {
if (mock) {
return await mockResponse(mockAsset);
}
try {
final response = await _dio.delete(
path,
data: data,
queryParameters: queryParameters,
options: options,
);
return response.data;
} catch (exception) {
final e = _errorHandler?.handle(exception);
if (e != null) {
throw e;
} else {
rethrow;
}
}
}
Future<T> patch<T>(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
bool mock = false,
String? mockAsset,
}) async {
if (mock) {
return await mockResponse(mockAsset);
}
try {
final response = await _dio.patch(
path,
data: data,
queryParameters: queryParameters,
options: options,
);
return response.data;
} catch (exception) {
final e = _errorHandler?.handle(exception);
if (e != null) {
throw e;
} else {
rethrow;
}
}
}
Future<dynamic> mockResponse(String? mockAsset) async {
assert(mockAsset != null, 'Mock asset should not null to mock mode');
try {
final response = jsonDecode(await rootBundle.loadString(mockAsset!));
return response;
} catch (exception) {
final e = _errorHandler?.handle(exception);
if (e != null) {
throw e;
} else {
rethrow;
}
}
}
}
import 'package:base/base.dart';
import 'package:module_banking/module_banking.dart';
class BankSlipPayment {
final String transactionId;
final String externalIdentifier;
final String receipt;
final String authenticationCode;
final BankSlipPaymentStatus status;
BankSlip bankSlip;
BankSlipPayment({
String? transactionId,
String? externalIdentifier,
String? receipt,
String? authenticationCode,
BankSlipPaymentStatus? status,
BankSlip? bankSlip,
}) : transactionId = transactionId ?? '',
externalIdentifier = externalIdentifier ?? '',
receipt = receipt ?? '',
authenticationCode = authenticationCode ?? '',
status = status ?? BankSlipPaymentStatus.created,
bankSlip = bankSlip ?? BankSlip();
factory BankSlipPayment.fromJson(Map<String, dynamic> json) {
return BankSlipPayment(
transactionId: json.getString('transactionId'),
externalIdentifier: json.getString('externalIdentifier'),
receipt: json.getString('receipt'),
authenticationCode: json.getString('authenticationCode'),
status: json.getEnum('status', BankSlipPaymentStatusMapper.fromString),
bankSlip: json.getObject('bankSlip', BankSlip.mapper),
);
}
Map<String, dynamic> toJson() => {
'transactionId': transactionId,
'externalIdentifier': externalIdentifier,
'receipt': receipt,
'authenticationCode': authenticationCode,
'status': status.name,
'bankSlip': bankSlip.toJson(),
}..removeWhere((e, dynamic v) => v == null);
/// Util method to clone classes
BankSlipPayment clone() => BankSlipPayment.fromJson(toJson());
/// Util method pass fromJson mapper as a parameter
static BankSlipPayment mapper(dynamic map) =>
BankSlipPayment.fromJson(map as Map<String, dynamic>);
}
import 'dart:io';
import 'package:noodle_validators/noodle_validators.dart';
import 'log.dart';
extension JsonUtils on Map<String, dynamic> {
T getSafeItem<T>(String key, {required T defaultValue}) {
if (containsKey(key)) {
return this[key];
}
return defaultValue;
}
T getValue<T>(String key, T defaultValue) {
return jsonSafeValue(this, key, defaultValue);
}
T? getNestedValue<T>(List<String> keys) {
return jsonNestedValue(this, keys);
}
String getString(String key) {
return jsonSafeValue(this, key, '');
}
String? getStringNull(String key) {
return jsonSafeValue<String?>(this, key, null);
}
String getStringFromKeys(List<String> keys) {
String? value;
for (final key in keys) {
if (containsKey(key)) {
value = getString(key);
break;
}
}
if (value != null) {
return value;
}
return getString(keys[0]);
}
File? getFile(String key) {
try {
return File(getString(key));
} catch (_) {
return null;
}
}
File? getFileFromKeys(List<String> keys) {
File? value;
for (var element in keys) {
if (containsKey(element)) {
value = getFile(element);
continue;
}
}
return value!;
}
int getInt(String key) {
return jsonSafeValue(this, key, 0);
}
int? getIntNull(String key) {
return jsonSafeValue<int?>(this, key, null);
}
int getIntFromKeys(List<String> keys) {
int? value;
for (var element in keys) {
if (containsKey(element)) {
value = getInt(element);
continue;
}
}
if (value != null) {
return value;
}
return getInt(keys[0]);
}
double getDouble(String key) {
try {
return double.parse(this[key].toString());
} catch (_) {
return 0.0;
}
}
double? getDoubleNull(String key) {
return jsonSafeValue<double?>(this, key, null);
}
double getDoubleFromKeys(List<String> keys) {
double? value;
for (var element in keys) {
if (containsKey(element)) {
value = getDouble(element);
continue;
}
}
if (value != null) {
return value;
}
return getDouble(keys[0]);
}
bool getBool(String key) {
return jsonSafeValue(this, key, false);
}
bool? getBoolNull(String key) {
return jsonSafeValue<bool?>(this, key, null);
}
bool getBoolFromKeys(List<String> keys) {
bool? value;
for (var element in keys) {
if (containsKey(element)) {
value = getBool(element);
continue;
}
}
if (value != null) {
return value;
}
return getBool(keys[0]);
}
T? getObject<T>(String key, T Function(Map<String, dynamic>) itemMap) {
return jsonSafeMap(this, key, itemMap);
}
T getEnum<T>(String key, T Function(String?) enumMap) {
return jsonSafeEnum(this, key, enumMap);
}
T getEnumFromKeys<T>(List<String> keys, T Function(String?) enumMap) {
T? value;
for (var element in keys) {
if (containsKey(element)) {
value = jsonSafeEnum(this, element, enumMap);
continue;
}
}
if (value != null) {
return value;
}
return jsonSafeEnum(this, keys[0], enumMap);
}
List<T> getList<T>(String key, [T Function(Map<String, dynamic>)? itemMap]) {
return jsonListValue(this, key, itemMap);
}
DateTime? getDate(String key) {
return jsonDateValue(this, key);
}
DateTime? getDateFromKeys(List<String> keys) {
DateTime? value;
for (var element in keys) {
if (containsKey(element)) {
value = getDate(element);
continue;
}
}
return value;
}
Map<String, dynamic> removeNulls() {
removeWhere((key, value) => value == null);
return this;
}
}
extension JsonListUtils on List<dynamic> {
List<T> asList<T>(T Function(Map<String, dynamic>) itemMap) {
return jsonAsList(this, itemMap);
}
}
DateTime? jsonDateValue(Map<String, dynamic> json, String key) {
if (json[key] is int) {
return DateTime.fromMillisecondsSinceEpoch(json[key], isUtc: true);
}
return (json[key] as String?)?.toDate();
}
T jsonSafeValue<T>(Map<String, dynamic> json, String key, T defaultValue) {
try {
final value = json[key];
if (value != null) {
return value;
} else {
return defaultValue;
}
} catch (e) {
return defaultValue;
}
}
T? jsonSafeMap<T>(Map<String, dynamic> json, String key,
T Function(Map<String, dynamic>) itemMap) {
if (json.containsKey(key)) {
try {
return itemMap(json[key]);
} catch (e) {
return null;
}
}
return null;
}
T jsonSafeEnum<T>(
Map<String, dynamic> json, String key, T Function(String?) enumMap) {
try {
return enumMap(json[key]);
} catch (e) {
return enumMap(null);
}
}
List<T> jsonListValue<T>(Map<String, dynamic> json, String key,
[T Function(Map<String, dynamic>)? itemMap]) {
try {
final list = (json[key] as List<dynamic>)
..removeWhere((element) => element == null);
if (itemMap != null) {
return list.map((dynamic e) => itemMap(e)).toList();
}
return list.map((e) => e as T).toList();
} catch (e) {
return [];
}
}
List<T> jsonAsList<T>(
List<dynamic> json, T Function(Map<String, dynamic>) itemMap) {
try {
return json.map((dynamic e) => itemMap(e)).toList();
} catch (e) {
return [];
}
}
T? jsonNestedValue<T>(Map<String, dynamic> json, List<String> nestedKeys) {
try {
if (nestedKeys.length == 1) {
return json[nestedKeys[0]];
} else if (nestedKeys.length == 2) {
return json[nestedKeys[0]][nestedKeys[1]];
} else if (nestedKeys.length == 3) {
return json[nestedKeys[0]][nestedKeys[1]][nestedKeys[2]];
} else if (nestedKeys.length == 4) {
return json[nestedKeys[0]][nestedKeys[1]][nestedKeys[2]][nestedKeys[3]];
} else if (nestedKeys.length == 5) {
return json[nestedKeys[0]][nestedKeys[1]][nestedKeys[2]][nestedKeys[3]]
[nestedKeys[4]];
} else {
safeLog('implements json getJsonValue from ${nestedKeys.length}');
return null;
}
} catch (e) {
return null;
}
}
import 'package:base/base.dart';
import 'package:module_banking/module_banking.dart';
class UserLimits {
final String taxId;
final double? requestedDailyLimit;
final double? requestedNightlyLimit;
UserLimits({
String? taxId,
this.requestedDailyLimit,
this.requestedNightlyLimit,
}) : taxId = taxId ?? "";
factory UserLimits.fromJson(Map<String, dynamic> json) {
return UserLimits(
taxId: json.getString("taxId"),
requestedDailyLimit: json.getValue<double?>("requestedDailyLimit", null),
requestedNightlyLimit:json.getValue<double?>("requestedNightlyLimit", null),
);
}
Map<String, dynamic> toJson() => {
'taxId': taxId,
'requestedDailyLimit': requestedDailyLimit,
'requestedNightlyLimit': requestedNightlyLimit,
}..removeWhere((e, dynamic v) => v == null);
/// Util method to clone classes
UserLimits clone() => UserLimits.fromJson(toJson());
/// Util method pass fromJson mapper as a parameter
static UserLimits mapper(dynamic map) =>
UserLimits.fromJson(map as Map<String, dynamic>);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment