使用 'Dart Frog' 體驗(yàn) Dart 服務(wù)端開(kāi)發(fā)

引言

Dart官網(wǎng)上看到兩個(gè)現(xiàn)成的服務(wù)端框架,作為技術(shù)棧積累,體驗(yàn)了一把 Dart Frog猾昆,并整理了這篇文章。

安裝 Dart Frog

首先是 dart 環(huán)境的要求 Dart Frog requires Dart ">=2.19.0 <3.0.0"

  • 從 pub.dev 安裝 dart_frog 命令行
dart pub global activate dart_frog_cli

安裝完畢如下:


Dart Frog 創(chuàng)建項(xiàng)目

  • 使用命令行創(chuàng)建一個(gè) dart frog 項(xiàng)目
dart_frog create 項(xiàng)目名稱

例如創(chuàng)建一個(gè)項(xiàng)目名為:dart_frog_server

目錄結(jié)構(gòu)如下:


使用命令行開(kāi)啟服務(wù) dart_frog dev

image.png

打開(kāi)瀏覽器訪問(wèn)能看到正常返回即表示服務(wù)已成功開(kāi)啟:


下面我們來(lái)創(chuàng)建自己的 API 路由

創(chuàng)建 Router

Dart Frog 中骡苞,我們創(chuàng)建的所有路由需要放置在 /routes 目錄中

  • 例如在 routes 目錄內(nèi)新建文件夾 /pages垂蜗,創(chuàng)建一個(gè)通配符路由(通配符路由概念請(qǐng)看截圖內(nèi)注解)
image.png

請(qǐng)求效果如下:

  • 利用通配符路由楷扬,我們可以做 Api 的邏輯分配,例如:
Future<Response> onRequest(
  RequestContext context,
  String action,
) async {
  // 根據(jù)不同的接口路徑贴见,分配不同的api邏輯處理層
  switch (action) {
    case 'add':
      return Response(body: 'arrival add - api');
    case 'query':
      return Response(body: 'arrival query - api');
    default:
      return Response(statusCode: 404);
  }
}
image.png

獲取請(qǐng)求內(nèi)傳參

通過(guò) RequestContext 對(duì)象可獲取請(qǐng)求內(nèi)各參數(shù):

  • 獲取請(qǐng)求類型
final method = context.request.method.value;  //返回 POST/GET
  • 獲取 Headers
final headers = context.request.headers;
  • 獲取 Get 入?yún)?/li>
final params = context.request.uri.queryParameters; //返回 Map<String, String>
  • 獲取 Post 入?yún)?/li>
final body = await context.request.body();

業(yè)務(wù)開(kāi)發(fā)中常使用 Post 方式傳入 Json 數(shù)據(jù)作為入?yún)⒑嫫唬覀兛梢宰龇庋b提供便捷獲取數(shù)據(jù):

import 'package:dart_frog/dart_frog.dart';

extension ExRequest on RequestContext {
  Future<Map<String, dynamic>> get postParams async {
    late Map<String, dynamic> bodyParams;
    // 接收 post 傳參
    try {
      bodyParams =
          await request.json().then((value) => value as Map<String, dynamic>);
    } catch (e) {
      bodyParams = {};
    }
    return bodyParams;
  }
}

修改上面通配符路由中代碼,如下:

import 'package:dart_frog/dart_frog.dart';
import '../exension/ex_request.dart';

Future<Response> onRequest(
  RequestContext context,
  String action,
) async {
  final json = await context.postParams;
  late String targetApi;
  switch (action) {
    case 'add':
      targetApi = 'arrival add - api';
    case 'query':
      targetApi = 'arrival query - api';
    default:
      return Response(statusCode: 404);
  }
  final response = <String, dynamic>{};
  response['target'] = targetApi;
  response['postParams'] = json; //將獲取到的Post傳參打印出來(lái)
  return Response.json(body: response);
}

訪問(wèn)/pages/add請(qǐng)求蝇刀,添加 post 入?yún)⒚樱祷亟Y(jié)果如下:

image.png

Middleware 中間件

Dart Frog 中的中間件允許在處理請(qǐng)求之前和之后執(zhí)行代碼⊥趟觯可以修改入站請(qǐng)求和出站響應(yīng)捆探,提供依賴項(xiàng),等等!

注意:routes 目錄內(nèi)只能含有一個(gè) _middleware.dart 文件站粟,為所有入站請(qǐng)求執(zhí)行的中間件黍图。

1. AOP 操作(日志示例)

  • 利用中間件,我們可以在每條網(wǎng)絡(luò)請(qǐng)求前后添加日志:


    image.png

請(qǐng)求http://127.0.0.1:8080/pages/add奴烙,查看控制臺(tái)打印結(jié)果:

image.png
  • 如果不想自己寫日志打印助被,dart frog 提供了一個(gè)日志打印封裝
import 'package:dart_frog/dart_frog.dart';

Handler middleware(Handler handler) {
  return handler.use(requestLogger());
}

重新發(fā)起請(qǐng)求,控制臺(tái)打印結(jié)果:

image.png

2. 依賴注入

  • 中間件可用于通過(guò)提供者將依賴項(xiàng)注入 RequestContext切诀。例如揩环,修改上面的 _middleware.dart 文件:
import 'package:dart_frog/dart_frog.dart';

final _dataSource = DataSource();

Handler middleware(Handler handler) {
  return handler
      .use(requestLogger())
      .use(provider<DataSource>((_) => _dataSource));
}

class DataSource {
  //模擬獲取異步數(shù)據(jù)
  Future<String> mockFetchData() async {
    await Future.delayed(const Duration(seconds: 3));
    return 'mockFutureData is 李小轟';
  }
}

如上代碼,新建類 DataSource 提供方法模擬數(shù)據(jù)庫(kù)異步查詢幅虑,我們?cè)?server 生命周期內(nèi)維護(hù)了一個(gè) dataSource 實(shí)例丰滑,而不需要在每個(gè) request 中新建實(shí)例。

在 request 中通過(guò) context 上下文獲取 dataSource 實(shí)例:

image.png

請(qǐng)求結(jié)果如下:

image.png

關(guān)于 Dart Frog 部署

創(chuàng)建一個(gè)包含 DockerFile 的生產(chǎn)構(gòu)建倒庵,這樣你就可以部署到任何地方:

dart_frog build

demo 代碼已上傳 : https://github.com/liyufengrex/dart_frog_server

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末褒墨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子擎宝,更是在濱河造成了極大的恐慌郁妈,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绍申,死亡現(xiàn)場(chǎng)離奇詭異噩咪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)极阅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門胃碾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人涂屁,你說(shuō)我怎么就攤上這事书在』椅埃” “怎么了拆又?”我有些...
    開(kāi)封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵儒旬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我帖族,道長(zhǎng)栈源,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任竖般,我火速辦了婚禮甚垦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涣雕。我一直安慰自己艰亮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布挣郭。 她就那樣靜靜地躺著迄埃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兑障。 梳的紋絲不亂的頭發(fā)上侄非,一...
    開(kāi)封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音流译,去河邊找鬼逞怨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛福澡,可吹牛的內(nèi)容都是我干的叠赦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼竞漾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼眯搭!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起业岁,我...
    開(kāi)封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鳞仙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后笔时,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棍好,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年允耿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了借笙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡较锡,死狀恐怖业稼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚂蕴,我是刑警寧澤低散,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布俯邓,位于F島的核電站,受9級(jí)特大地震影響熔号,放射性物質(zhì)發(fā)生泄漏稽鞭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一引镊、第九天 我趴在偏房一處隱蔽的房頂上張望朦蕴。 院中可真熱鬧,春花似錦弟头、人聲如沸吩抓。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)琴拧。三九已至,卻和暖如春嘱支,著一層夾襖步出監(jiān)牢的瞬間蚓胸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工除师, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沛膳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓汛聚,卻偏偏與公主長(zhǎng)得像锹安,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子倚舀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容