iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Mobile Development

在 Flutter 開發旅程的手札系列 第 6

Flutter Package - 串接api(二)

昨天已經有介紹如何串接API,以及教大家如何GET API資料,今天我們就來介紹POST

在api.dart檔案裡面多一個RestApi(因路徑與昨天使用的是不同的,因此需要再重新建立一個Client),api是使用Postman Echo

import 'package:json_annotation/json_annotation.dart';
import 'package:retrofit/retrofit.dart';
import 'package:dio_http/dio_http.dart';

part 'api.g.dart';

@RestApi(baseUrl: "https://postman-echo.com")
abstract class PostClient {
  factory PostClient(Dio dio, {String baseUrl}) = _PostClient;

  @POST("/post")
  Future<PostDataResponse> postApiData(@Body() dynamic data);
}

建立一個post_data_response.dart

import 'package:json_annotation/json_annotation.dart';

part 'post_data_response.g.dart';

@JsonSerializable()
class PostDataResponse {
  PostData data;
  PostDataResponse({
    required this.data,
  });
  factory PostDataResponse.fromJson(Map<String, dynamic> json) => _$PostDataResponseFromJson(json);
}

@JsonSerializable()
class PostData {
  String content;
  PostData({
    required this.content,
  });
  factory PostData.fromJson(Map<String, dynamic> json) => _$PostDataFromJson(json);
}


在定義好的API抽象類別後, 需要透過Terminal下指令,進行Code Generation, 以便自動產生對抽象類別實作的具象子類別:

flutter pub run build_runner build --delete-conflicting-outputs

執行好後,會發現產出了一個新的檔案,post_data_response.g.dart,api.g.dart裡面的內容也會有調整

https://ithelp.ithome.com.tw/upload/images/20220921/20152683Byijgu7HWO.png


在app_repository.dart 的AppRepository class內加入PostClient

import 'package:dio/dio.dart';
import 'package:flutter_api_demo/post_data_response.dart';

import 'api.dart';

class AppRepository {
  final PostClient _postClient = PostClient(Dio());
  Future<PostDataResponse> postApiData(dynamic body) async {
    return _postClient.postApiData(body);
  }
}


透過Button傳送postApiData範例

     ElevatedButton(
              onPressed: () async {
                final apiResponse = await RepositoryProvider.of<AppRepository>(context).postApiData({
                  "content": "Test Data",
                });
                ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                  content: Text(apiResponse.data.content),
                ));
              },
              child: const Text("Post Button"),
            )

範例完成圖
https://ithelp.ithome.com.tw/upload/images/20220921/20152683R4XoZGaXE3.png


補充說明,dynamic的做法不是一個很嚴謹的做法,但可以幫助我們在初期比較好入手api。在開發上,我們會有一個Request的檔案,專門用來存POST的資料

建立一個post_data_request.dart檔案,輸入下方程式碼

import 'package:json_annotation/json_annotation.dart';

part 'post_data_request.g.dart';

@JsonSerializable()
class PostDataRequest {
  String content;
  PostDataRequest({
    required this.content,
  });
  Map<String, dynamic> toJson() => _$PostDataRequestToJson(this);
}


在api.dart檔案將

  @POST("/post")
  Future<PostDataResponse> postApiData(@Body() dynamic data);

更改為

  @POST("/post")
  Future<PostDataResponse> postApiData(@Body() PostDataRequest data);

要記得import 'package:flutter_api_demo/post_data_request.dart';

再跑一次,讓檔案更新

flutter pub run build_runner build --delete-conflicting-outputs

https://ithelp.ithome.com.tw/upload/images/20220921/20152683obn9e3cVGR.png


在app_repository.dart將

  final PostClient _postClient = PostClient(Dio());
  Future<PostDataResponse> postApiData(dynamic body) async {
    return _postClient.postApiData(body);
  }

更改為

  final PostClient _postClient = PostClient(Dio());
  Future<PostDataResponse> postApiData(PostDataRequest body) async {
    return _postClient.postApiData(body);
  }

要記得import 'package:flutter_api_demo/post_data_request.dart';


透過Button傳送postApiData範例

ElevatedButton(
              onPressed: () async {
                final apiResponse = await RepositoryProvider.of<AppRepository>(context).postApiData(PostDataRequest(
                  content: "Test Data",
                ));
                ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                  content: Text(apiResponse.data.content),
                ));
              },
              child: const Text("Post Button"),
            )

上一篇
Flutter Package - 串接api(一)
下一篇
Flutter Package - 串接api(三)
系列文
在 Flutter 開發旅程的手札30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言