Api Request
⚡ Classes that take care of one specific task.
This package introduces a new way of organising the logic of your flutter api applications by focusing on the actions your api provide.
Instead of creating service for all api's, it allows you to create a dart class that handles a specific api request and execute that class.
Why
- Help developers follow single responsibility principle (SRP)
- Small dedicated classes makes the code easier to test
- Action classes can be callable from multiple places in your app
- Small dedicated classes really pay off in complex apps
- Global Config
Adding Api Request to your project
In your project's pubspec.yaml
file,
- Add api_request latest version to your dependencies.
# pubspec.yaml
dependencies:
api_request: ^<latest version>
Config
import 'package:api_request/api_request.dart';
void main() {
/// global config api requests;
ApiRequestOptions.instance?.config(
/// set base url for all request
baseUrl: 'https://jsonplaceholder.typicode.com/',
/// set token type to 'Bearer '
tokenType: ApiRequestOptions.bearer,
/// set token as string api request action will with is if auth is required
token: '1|test-token',
/// we will call this method to get token in run time -- method must be return string
getToken: () => yourMethodToGetToken(),
/// we will call this method to get token in run time -- method must be return Future<string>
getAsyncToken: () => yourAysncMethodToGetToken(),
/// send default query params for all requests
defaultQueryParameters: {'locale': 'ar'},
/// send default interceptors for all requests
interceptors: [],
/// enableLog for request && response default true
enableLog: true,
);
runApp(MyApp());
}
- and from any pace of your code you can change config
ApiRequestAction Action
that is sample call api request by create class extends by ApiRequestAction<YourHandelResponse>
class PostsRequestAction extends ApiRequestAction<PostsResponse> {
@override
bool get authRequired => false;
@override
String get path => 'posts';
@override
RequestMethod get method => RequestMethod.GET;
@override
ResponseBuilder<PostsResponse> get responseBuilder =>
(list) => PostsResponse.fromList(list);
}
Call ApiRequestAction
PostsResponse response = await PostsRequestAction().execute();
ApiRequest
when need to send data with this request mix your class with ApiRequest
class LoginApiRequest with ApiRequest{
final String email;
final String password;
LoginApiRequest({required this.email,required this.password});
@override
Map<String, dynamic> toMap() => {
'email': this.email, 'password': this.password
};
}
Use ApiRequest with RequestAction
class LoginRequestAction extends RequestAction<AuthResponse, LoginApiRequest>{
LoginRequestAction(LoginApiRequest request) : super(request);
@override
bool get authRequired => false;
@override
String get path => 'login';
@override
RequestMethod get method => RequestMethod.POST;
@override
ResponseBuilder<AuthResponse> get responseBuilder => (map) => AuthResponse.fromMap(map);
}
Call LoginRequestAction Action
LoginApiRequest request = LoginApiRequest(
email: 'test@test.com',
password: '123123'
);
AuthResponse response = await LoginRequestAction(request).execute();
Dynamic Path
- example to send data in path you need to add vars in path like this /{var}/
- and in your request data add var name with your value like this:
class PostRequestAction extends ApiRequestAction<Post> {
final int? id;
PostRequestAction({this.id});
@override
Map<String, dynamic> toMap() => {
'id': this.id,
};
@override
bool get authRequired => false;
@override
String get path => 'posts/{id}';
@override
RequestMethod get method => RequestMethod.GET;
@override
ResponseBuilder<Post> get responseBuilder => (map) => Post.fromMap(map);
}
Action Events
listing for action events:
- onInit
- onStart
- onSuccess
- onError
class PostRequestAction extends ApiRequestAction<Post> {
/// action implement
@override
Function get onInit => () => print('Action Init');
@override
Function get onStart => () => print('Action Start');
@override
SuccessHandler<Post> get onSuccess =>
(post) => print('Action Success ${post?.id}');
@override
ErrorHandler get onError => (error) => print('Action Error ${error.message}');
}
onQueue
if you don't wait result from action , run action onQueue
and listen by subscribe
:
onSuccess
OnError
OnDone
PostRequestAction action = PostRequestAction(id: id);
// use action events setter
action.onStart = () => print('Action Start Form Ui');
action.onSuccess = (post) => print('Action Success Form Ui ${post?.id}');
action.onError = (error) => print('Action Error Form Ui ${error.message}');
// use action subscribe
action.subscribe(
onSuccess: (response) {
print('response Post Id: ${response.id}');
},
onError: (error) {
if (error is ApiRequestError) {
print("response Error ${error.requestOptions?.uri.toString()}");
}
},
onDone: () {
print("Hi I done");
},
);
action.onQueue();
Performance Report
get performance report for all called actions
- print in console log
print("${ApiRequestPerformance.instance.toString()}");
- Map Reports
Map<String?, PerformanceReport?> actionsReport = ApiRequestPerformance.instance?.actionsReport