ورود و عضویت
0
سبد خرید شما خالی است
0
سبد خرید شما خالی است

آموزش کار با رتروفیت Retrofit در فلاتر

1 دیدگاه

فریمورک فلاتر دارای ماژول های network و JSON serialization می باشد که از آنها برای ارتباط با API میتوانیم استفاده کنیم.

اما برای اینکه بتونیم به شکل حرفه ای تر با وب سرویس ها در فلاتر کار کنیم و از قابلیت هایی مثل هدر های پویا, پارامتر های گوناکون, امنیت بیشتر برخوردار باشیم کتابخانه رتروفیت گزینه بسیار مناسبی است.

رتروفیت کتابخانه مخصوص ارتباط با API میباشد که برای زبان های جاوا و کاتلین نیز در برنامه نویسی اندروید از آن استفاده میشود.

برای استفاده از Retrofit پکیج های زیر را در فایل pubspec.yaml اضافه کنید.

dependencies:
retrofit: ^1.3.4+1
dio: ^3.0.10
built_value: ^7.1.0
json_annotation: ^3.1.0
dev_dependencies:
retrofit_generator: ^1.3.7+5
build_runner: ^1.10.0
json_serializable: ^3.5.0
built_value_generator: ^7.1.0

Retrofit در واقع یک کلاینت برای پکیج Dio می باشد که استفاده از API را آسان تر میکند.

JSON Serialization نیز برای ساختن کلاس های مدل استفاده می شود.

کلاس های ApiRequest 

در ابتدا نیاز داریم تا یک سری کلاس abstract ایجاد کنیم.

برای این آموزش از وب سرویس آدرس زیر استفاده میکنیم.

https://gorest.co.in/public-api/users
class Apis {
  static const String users = '/users';
}
@RestApi(baseUrl: "https://gorest.co.in/public-api/")
abstract class ApiClient {
  factory ApiClient(Dio dio, {String baseUrl}) = _ApiClient;
  @GET(Apis.users)
  Future<ResponseData> getUsers();
}

کلاس ApiClient به عنوان repository عمل میکنه و کار مدیریت صدا زدن متد های وب سرویس را انجام میدهد.

در کد بالا آبجکت _ApiClient یک خطا را نشان میدهد که در ادامه با تکمیل کردن برنامه این مشکل رفع میشود.

در قسمت baseUrl باید آدرس کلی API خود را وارد کنید.

استفاده از Annotations ها در متد ها مشخص میکند که چه نوع درخواستی به سرور ارسال شود.

برای مثال متد getUsers از نوع درخواست GET مشخص شده است و آدرس آن هم Apis.users است که به انتهای baseUrl مقدار ‘user/’ اضافه میشود.

Annotations هایی که برای یک متد میتوانید قرار دهید مقادیر زیر هستند:

  • GET
  • PUT
  • POST
  • DELETE 
  • PATCH
  • HEADER

مثال های عملی استفاده از درخواست های مختلف میتونه به شکل زیر باشه.

//Dynamic headers
@GET("/posts")
Future<List<Post>> getPosts(@Header("Content-Type") String contentType );
@GET("/comments")
@Headers(<String, dynamic>{ //Static header
  "Content-Type" : "application/json",
  "Custom-Header" : "Your header"
})
Future<List<Comment>> getAllComments();
@GET("/posts/{id}")
Future<Post> getPostFromId(@Path("id") int postId);
@GET("/comments?postId={id}")
Future<Comment> getCommentFromPostId(@Path("id") int postId);
@GET("/comments")
Future<Comment> getCommentFromPostIdWithQuery(@Query("postId") int postId); //This yields to "/comments?postId=postId
@DELETE("/posts/{id}")
Future<void> deletePost(@Path("id") int postId);
@POST("/posts")
Future<Post> createPost(@Body() Post post);

اگر به متد getPostFromId دقت کنید متوجه میشوید که برای قرار دادن پارامترهای داینامیک در رتروفیت باید آنها را داخل یک {} قرار دهید و همچنین از @Path نیز استفاده کنید.

@Body زمانی کاربرد دارد که میخواهید آبجکتی را در داخل body به سرور ارسال کنید.

@Query برای اضافه کردن مقادیری به url استفاده میشود.

@Headers هم برای ارسال هدر به شکل پویا کاربرد دارد.

برای حل خطایی که قبل تر برخورد کردیم با آن دستور زیر را در ترمینال وارد کنید.

flutter pub run build_runner build

دستور بالا باعث ساخته شدن فایل api_client.g.dart می شود که شامل تمام اطاعات لازم برای ساخت نمونه از رتروفیت می باشد.

اگر تغییری در قسمت ApiClient ایجاد کردید باز نیاز دارید تا این دستور را اجرا کنید.

ساخت کلاس مدل

در این مثال قرار هست که لیست کاربران را از طریق وب سرویس دریافت کنیم که نمونه ان به شکل زیر است.

{
  code: 200,
  meta: {
    pagination: {
      total: 1676,
      pages: 84,
      page: 1,
      limit: 20
    }
  },
  data: [
    {
      id: 1,
      name: "Mrs. Somnath Namboothiri",
      email: "somnath_namboothiri_mrs@baumbach-nitzsche.com",
      gender: "Female",
      status: "Active",
      created_at: "2020–08–31T03:50:04.198+05:30",
      updated_at: "2020–08–31T03:50:04.198+05:30"
    },
    
  ]
}

در مرحله بعدی فایلی به نام data.dart ایجاد میکنیم کدهای مربوط به کلاس مدل را در آن قرار میدهیم.

اینجا دو نکته مهم وجود داره. در حالت های عادی برای ساخت کلاس مدل به شکل زیر کار Serialization را انجام میدادیم.

class User {
  int id;
  String name;
  String email;
  String gender;
  String status;
  String created_at;
  String updated_at;
  User({this.id, this.name, this.email,this.gender, this.status, this.created_at, this.updated_at});
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['name'],
      email: json['email'],
      gender: json['gender'],
      status: json['status'],
      created_at: json['created_at'],
      updated_at: json['updated_at'],
    );
  }
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'email': email,
      'gender': gender,
      'status': status,
      'created_at': created_at,
      'updated_at': updated_at,
    };
  }
}

کتابخانه Retrofit به شکل خودکار جیسون را به آبجکت کلاس User تبدیل میکند و نیازی به کدهای تکراری نوشتن نیست.

import 'package:json_annotation/json_annotation.dart';
part 'data.g.dart';
@JsonSerializable()
class User{
  int id;
  String name;
  String email;
  String gender;
  String status;
  String created_at;
  String updated_at;
  User({this.id, this.name, this.email,this.gender, this.status, this.created_at, this.updated_at});
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}
@JsonSerializable()
class ResponseData{
  int code;
  dynamic meta;
  List<dynamic>data;
  ResponseData({this.code, this.meta, this.data});
  factory ResponseData.fromJson(Map<String, dynamic> json) => _$ResponseDataFromJson(json);
  Map<String, dynamic> toJson() => _$ResponseDataToJson(this);
}

در این حالت باز به خطا برخورد میکنید که نیاز دارید دستور بالا را دوباره استفاده کنید.

هنگام ساخت کلاس حتما از @JsonSerializable() نیز باید استفاده کنید.

تمام کارهایی که لازم بود را انجام دادیم و حالا نوبت به استفاده از وب سرویس هست.

FutureBuilder<ResponseData> _buildBody(BuildContext context) {
  final client = ApiClient(Dio(BaseOptions(contentType: "application/json")));
  return FutureBuilder<ResponseData>(
    future: client.getUsers(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        final ResponseData posts = snapshot.data;
        return _buildListView(context, posts);
      } else {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
    },
  );
}

خیلی ساده از کلاس ApiClient یک نمونه میسازیم و متدی که به آن نیاز داریم را صدا میزنیم.

در این مثال ما فقط یک متد به نام getUsers داشتیم.

یک پاسخ به “آموزش کار با رتروفیت Retrofit در فلاتر”

  1. mehdi گفت:

    با سلام و وقت بخیر
    چرا بعد از زدن دستور در ترمینال api_client.g.dart ساخته نمیشه
    ممنون میشم راهنمایی کنین

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Hesam
02 ژانویه 2021
آموزش فارسی فلاتر
آموزش فارسی flutter