Manajemen API Menggunakan Dio

Halo semua, kali ini kita akan belajar bagaimana sih mengolah atau memanajemen Rest API di Flutter. Apa saja yang akan kita pelajari kali ini?

  • Apa itu Dio?
  • Pengujian dengan data API
  • Mendefinisikan model class
  • Inisialisasi
  • Memilih dan menentukan global config
  • Mendefinisikan request
  • Upload files
  • Interceptors

Apa itu Dio ?

Networking library developed by Flutter China. It is powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout etc.

Pengujian dengan data API

Contoh request dan response data API kita menggunakan https://reqres.in/api/users/3

{
  "data": {
    "id": 3,
    "email": "[email protected]",
    "first_name": "Emma",
    "last_name": "Wong",
    "avatar": "https://reqres.in/img/faces/3-image.jpg"
  },
  "support": {
    "url": "https://reqres.in/#support-heading",
    "text": "To keep ReqRes free, contributions towards server costs are appreciated!"
  }
}

Mendefinisikan model class

Buatlah class “user” dan class “data” seperti berikut :

class User

import 'package:json_annotation/json_annotation.dart';
import 'data.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  User({
    required this.data,
  });

  Data data;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

class Data

import 'package:json_annotation/json_annotation.dart';

part 'data.g.dart';

@JsonSerializable()
class Data {
  Data({
    required this.id,
    required this.email,
    required this.firstName,
    required this.lastName,
    required this.avatar,
  });

  int id;
  String email;
  @JsonKey(name: 'first_name')
  String firstName;
  @JsonKey(name: 'last_name')
  String lastName;
  String avatar;

  factory Data.fromJson(Map<String, dynamic> json) => _$DataFromJson(json);
  Map<String, dynamic> toJson() => _$DataToJson(this);
}

Inisialisasi

import 'package:dio/dio.dart';

class ApiClient {
  final Dio dio = Dio();
}

Memilih dan Menentukan Global Config

final Dio dio = Dio(
  BaseOptions(
    baseUrl: 'https://reqres.in/api',
    connectTimeout: 5000,
    receiveTimeout: 3000,
  ),
);

Mendefinisikan Request

GET Request

Future<Response> getData(String endpoint, {Map<String, dynamic>? headers, CancelToken? cancelToken}) async {
  try {
    final response = await dio.get(
      Uri.encodeFull(endpoint),
      options: Options(headers: headers ?? getHeaders()),
      cancelToken: cancelToken,
    );
    return response;
  } catch (e) {
    throw handleException(e as Exception);
  }
}

Contoh Service

Future<User?> getUser({String? id}) async {
  User? user;
  try {
    final Response userData = await ApiClient.instance.getData('/users/$id');
    user = User.fromJson(userData.data);
  } on DioError catch (e) {
    print('Error sending request ${e.message}!');
  }
  return user;
}

Contoh Penggunaannya

userInfo = await UserService.instance.getUser(id: '2');

POST Request

Future<Response> postData(String endpoint, dynamic data, {Map<String, dynamic>? headers}) async {
  try {
    final response = await dio.post(
      Uri.encodeFull(endpoint),
      data: data,
      options: Options(headers: headers ?? getHeaders()),
    );
    return response;
  } catch (e) {
    throw handleException(e as Exception);
  }
}

PUT Request

Future<Response> putData(String endpoint, dynamic data, {Map<String, dynamic>? headers}) async {
  try {
    final response = await dio.put(
      Uri.encodeFull(endpoint),
      data: data,
      options: Options(headers: headers ?? getHeaders()),
    );
    return response;
  } catch (e) {
    throw handleException(e as Exception);
  }
}

DELETE Request

Future<Response> deleteData(String endpoint, {Map<String, dynamic>? headers}) async {
  try {
    final response = await dio.get(
      Uri.encodeFull(endpoint),
      options: Options(headers: headers ?? getHeaders()),
    );
    return response;
  } catch (e) {
    throw handleException(e as Exception);
  }
}

Upload Files

Future<Response> postMultipartData(String endpoint, File file) async {
  final Map<String, MultipartFile> multipartData = {
    'photo':
        await MultipartFile.fromFile(file.uri.path, filename: 'avatar.jpg'),
  };
  final formData = FormData.fromMap(multipartData);
  return postData(endpoint, formData, headers: getHeaders());
}

Interceptors

import 'package:dio/dio.dart';

class Logging extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    print('REQUEST[${options.method}] => PATH: ${options.path}');
    return super.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
    return super.onResponse(response, handler);
  }

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) {
    print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
    return super.onError(err, handler);
  }
}

Kesimpulan

Jadi, networking in flutter menggunakan Dio Package sangat memudahkan developer terutama Mobile Engineer untuk manajemen Rest API. Keep spirit and happy coding 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *