Russian

ETICON API

Library for working with http requests.

Pay attention to important changes since version 2.0.0!

The library for working with the network has been changed. Instead of http, Dio is now used.

If you want to use the new version in older projects, either update all requests, or replace the Api when using requests with OldApi. OldApi needs to be used exclusively for the requests themselves (get, post, patch, put).

However, some changes cannot be avoided, for example, abandoning the baseUrl in the initialization and replacing it with a list of urls. This was done to be able to interact with different services, while not my url.

The named parameter method has been removed from requests. Now you can pass both the method and the full url, respectively, rawGet, rawPost, rawPut, rawPatch have been removed.

It is also worth paying attention to the type of the returned data type, now the request can return either Map<String, dynamic> or the Response class.

Content

Initialization

First you need to initialize:

void main() async {
   await Api.init(urls: ['https://example.com/']);
   runApp(MyApp());
}

For the same type of behavior on the same error code, you can use onAllError. For example, when receiving a 401 code, send the user to the authorization screen.

void main() async {
   await Api.init(urls: ['https://example.com/'],
   onAllError: (err) {
         if (err.code == 401) Get.offAll(() => AuthScreenProvider());}
   );
   runApp(MyApp());
}

Methods

Fields RequestType Value
isAuth All If set to true, the request will be authorized
method All Accepts a string that is appended to baseURL
body POST, PUT, PATCH Accepts a request body in Map
query GET, DELETE Accepts parameters in Map
testmode All If set to true, show detailed information about the request

GET

future<void> getRequest() async {
     try{
       Map<String, dynamic> response = await Api.get('product', query: {"id": 5});
     } on APIException catch(error){
       print('ERROR CODE: ${error.code}');
     }
   }

POST

future<void> postRequest() async {
     try{
       Map<String, dynamic> response = await Api.post('product', body: {"id": 5});
     } on APIException catch(error){
       print('ERROR CODE: ${error.code}');
     }
   }

DELETE

future<void> deleteRequest() async {
     try{
       Map<String, dynamic> response = await Api.delete(method: 'product', query: {"id": 5}, isAuth: true);
     } on APIException catch(error){
       print('ERROR CODE: ${error.code}');
     }
   }

PUT

future<void> putRequest() async {
     try{
       Map<String, dynamic> response = await Api.put('product', body: {"id": 5}, isAuth: true);
     } on APIException catch(error){
       print('ERROR CODE: ${error.code}');
     }
   }

PATCH

Future<void> patchRequest() async {
     try{
       Map<String, dynamic> response = await Api.patch('product', body: {"id": 5}, isAuth: true);
     } on APIException catch(error){
       print('ERROR CODE: ${error.code}');
     }
   }

About CancelToken, onSendProgress and onReciveProgress can be read on the page Dio

Response type

For all requests, you can set the response type (ResponseType), unlike Dio, another type has been added that does not return a full-fledged class, but returns only Map<String, dynamic>, for this you need to use ResponseType.map_data (the default value in all requests) . In other cases, the Response class will return, similar to Dio.

{
   /// Response body. may have been transformed, please refer to [ResponseType].
   T? data;
   /// Response headers.
   header headers;
   /// The corresponding request info.
   options request;
   /// Http status code.
   int? statusCode;
   String? statusMessage;
   /// Whether redirect
   bool? isRedirect;
   /// redirect info
   List<RedirectInfo> redirects ;
   /// Returns the final real request uri (maybe redirect).
   Uri realUri;
   /// Custom field that you can retrieve it later in `then`.
   Map<String, dynamic> extra;
}

Headers

To declare global headers, you must use the method:

   Api.setHeaders({"Content-type": 'application/json'});

If no headers are set, the default header is Content-type : application/json

Note!!! that the *Authorization header is added automatically on an authorized request.

Headers can also be set and for a separate request I use the headers parameter, if the header key was declared globally, then it will be overwritten from the specified parameter.

Authorization

For authorized requests, you must set the value of the token. The set value will be written to the device memory. When using Api.init(), the token will be automatically unloaded from the device's memory.

   api.setToken('{your_token}');

Get a token:

   api.token;

Clear token:

   api.clearToken;

You can also check if the token is empty or not empty:

   Api.tokenIsEmpty;//return true or false
   api.tokenIsNotEmpty;//return true or false

If you are not using the Bearer type in the token, disable it:

void main() async {
   await Api.init(urls: ['https://example.com/'], bearerToken: false);
   runApp(MyApp());
}

Refresh token

by analogy with the authorization token, you can use the refresh token:

   Api.setRefreshToken('{your_token}');

Get a token:

   api.refreshToken;

Clear token:

   api.clearRefreshToken;

You can also check if the token is empty or not empty:

   Api.refreshTokenIsEmpty;//return true or false
   Api.refreshTokenIsNotEmpty;//return true or false

Set token expiration time in seconds:

   API.setExpire(3600);

Checking if the authorization token has expired:

   api.isTokenExpire;

Get the expiration date of the authorization token:

   api.expireDate;

Send MultiPart-Formdata

You can also submit FormData which will post data to multipart/form-data and support file uploads.

var formData = FormData.fromMap({
   'name': 'wendux',
   'age': 25,
   'file': await MultipartFile.fromFile('./text.txt',filename: 'upload.txt')
});
response = await Api.post('/info', data: formData);

Upload multiple files

There are two ways to add multiple files to FormData, the only difference is that the upload keys are different for array types。

FormData.fromMap({
   'files': [
     MultipartFile.fromFileSync('./example/upload.txt', filename: 'upload.txt'),
     MultipartFile.fromFileSync('./example/upload.txt', filename: 'upload.txt'),
   ]
});

The upload key eventually becomes "files[]". This is because many back-end services add a middle bracket to the key when they receive an array of files. If you don't need "[]", you should create FormData like this (don't use FormData.fromMap):

var formData = FormData();
formData.files.addAll([
   MapEntry('files',
     MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'),
   ),
   MapEntry('files',
     MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'),
   ),
]);

Test Mode

Test mode is a handy application development tool that shows complete request information (parameters, full URL, response body, etc.). In addition, this function disables all error handlers. The test mode can be set as global for all requests in the project:

void main() async {
   await Api.init(urls: ['https://example.com/'], globalTestMode: true);
   runApp(MyApp());
}

And on a separate request:

future<void> getRequest() async {
     try{
       Map<String, dynamic> response = await Api.get(method: 'product', isAuth: true, testMode: true);
     } on APIException catch(error){
       print('ERROR CODE: ${error.code}');
     }
   }

To disable test mode in the entire project, you can use disableAllTestMode:

void main() async {
   await Api.init(
     urls: ['https://example.com/'],
     globalTestMode: true, // Will be ignored
     disableAllTestMode: true
   );
   runApp(MyApp());
}

It is often necessary to receive various data from the server storage, for example, images, but the base link and the storage link sometimes do not match, or you have to manually enter the url each time.

To set a reference to the storage, it must be specified in the initialization:

void main() async {
   await Api.init(urls: ['https://example.com/'], storageUrl: 'https://example.com/storage/');
   runApp(MyApp());
}

Usage example:

Image.network(Api.dataFromStorage('image.png'));

UTF-8 decryption

There is built-in support for decoding in response to utf-8

void main() async {
   await Api.init(
     urls: ['https://example.com/'],
     ebableUtf8Decoding: true
   );
   runApp(MyApp());
}

Libraries

dart_eticon_api
eticon_api
Eticon API is a handy and simple package for handling http requests.