從零創(chuàng)建一個 Dart 服務端項目

前幾天看了咸魚的一篇文章 Flutter & Dart三端一體化開發(fā)
, 相信有一部分人想使用 Dart 嘗試編寫一些服務端的代碼.

DartVM 的性能已經和 JVM 非常接近, 再加上和 Nodejs 一樣的異步io的處理方式, 可以達到和 Nodejs 同級別的并發(fā)性能, 并且還有更好地運算性能, 完全可以替代大部分 Nodejs 的使用場景.

這篇文章將會帶大家從零創(chuàng)建一個 Dart 服務端項目, 本文會逐步覆蓋一下知識點:

  • 依賴庫的安裝
  • 編寫 API, 并且讀取 GET 請求的參數 和 POST 請求的 body
  • mongodb 或其他數據庫的連接
  • 編寫請求前置中間鍵, 并且擴展 db 對象至請求的上下文
  • 進行 AOT 編譯和部署

安裝 Dart

MacOS:

 $ brew tap dart-lang/dart
 $ brew install dart

Windows(使用 chocolatey 安裝):

c:\ choco install dart-sdk

或者根據 Dart官方文檔安裝

創(chuàng)建一個 Dart 項目

創(chuàng)建一個文件夾, 并且創(chuàng)建一個 pubspec.yaml 文件

$ mkdir your_project && cd your_project
$ touch pubspec.yaml

pubspec.yaml 文件內容:

name: your_project
version: 0.0.1
environment:
  sdk: '>=2.3.0 <3.0.0'

dependencies:
  serral: any

這里我們添加了一個依賴 serral 作為 express 或 koa 的替代品進行服務端開發(fā), 它的源碼只有 200 行, 并且約定了一套非常簡單的擴展方式, Serral API 文檔.

安裝依賴:

$ pub get

編寫你的第一個 Dart 服務

$ mkdir lib
$ touch lib/main.dart

編輯 lib/main.dart:

import 'package:serral/main.dart';

void main() {
  final app = Serral();

  // 默許跨域
  app.before(app.addCorsHeaders);

  // 添加前置中間鍵
  app.before((SerralCtx ctx) {
    print(ctx.request.uri.toString());
    ctx.context['dog'] = 100;
  });

  // 添加后置中間鍵
  app.after((SerralCtx ctx) {
    print('end');
  });

  // 捕獲某個路徑的請求
  app.GET('/', getHome);
  app.POST('/dog', postDog);

  app.serve(port: 5100);
}

// 實現該 GET 路由
void getHome(SerralCtx ctx) async {
  // 讀取 ctx.context, 檢查前置中間鍵是否生效
  print(ctx.context['dog']);
  // 查看請求路徑參數
  print(ctx.params);
  ctx.send(200, 'hello: ${ctx.context['dog']}');
}

// 實現該 POST 路由
void postDog(SerralCtx ctx) async {
  // 查看 post 請求的 body
  print(ctx.body);
  // 模擬異步, 檢查后置中間鍵是否生效
  await Future.delayed(Duration(milliseconds: 300));
  ctx.send(200, 'order');
}

啟動服務

$ dart lib/main.dart

好了, 服務已經啟動:

serral runing: http://127.0.0.1:5100

如何使用 Mongodb 或其他數據驅動

安裝 mongo_dart:

dev_dependencies:
  mongo_dart: any

方案 1, 利用 context 存儲驅動:

編寫代碼

import 'package:mongo_dart/mongo_dart.dart';

import 'package:serral/main.dart';

void main() async {
  Db db = new Db("mongodb://127.0.0.1:27017/test");
  await db.open();

  final app = Serral();

  app.before((SerralCtx ctx) {
    // add mongodb in context
    ctx.context['db'] = db;
  });

  app.GET('/', getHome);

  app.serve(port: 5100);
}

void getHome(SerralCtx ctx) async {
  Db db = ctx.context['db'];
  在請求過程中
  print(db);
  ctx.send(200, 'hello: ${ctx.context['dog']}');
}

方案 2, 使用 mixin 擴展 SerralCtx:

import 'package:mongo_dart/mongo_dart.dart';

import 'package:serral/main.dart';

// mixin 擴展 SerralCtx 來添加各種所需的對象
class MongoCtx with SerralCtx {
  Db db;
}

void main() async {
  Db db = new Db("mongodb://127.0.0.1:27017/test");
  await db.open();

  // 使用 MongoCtx 替換 SerralCtx 作為上下文
  final app = Serral(()=> MongoCtx());

  app.before((MongoCtx ctx) {
    // 在請求前置的中間鍵存儲 db 對象的引用
    ctx.db = db;
  });

  app.GET('/', getHome);

  app.serve(port: 5100);
}

void getHome(MongoCtx ctx) async {
  // 在請求響應中使用 db 對象
  print(ctx.db);
  ctx.send(200, 'hello: ${ctx.context['dog']}');
}

好的, 通過以上的例子我們可以很輕松的給服務添加前置或后置的中間鍵, 或者在擴展 context 對象的內容, 方便在請求響應時進行使用.

AOT編譯及部署

接下來我們要 DartVM 的性能, 我們將 source-code 進行 AOT 編譯, AOT編譯后相對于 source-code 可以提升1~2個數量級的性能:

AOT編譯:

dart2aot lib/main.dart lib/main.aot

使用 dartaotruntime 啟動生產版本:

dartaotruntime lib/main.aot

序也可以寫在最后, 不是嗎?

通過簡單的一點點代碼, 我們已經創(chuàng)建了一個 Dart API 服務, 并且進行了 AOT 編譯, 讓其更合適在生產環(huán)境下運行.

希望初學 Dart 的童鞋會有些許收獲, 謝謝閱讀.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末来颤,一起剝皮案震驚了整個濱河市般又,隨后出現的幾起案子溉奕,更是在濱河造成了極大的恐慌雄卷,老刑警劉巖庵佣,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惨好,死亡現場離奇詭異品擎,居然都是意外死亡蛮原,警方通過查閱死者的電腦和手機仰剿,發(fā)現死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門创淡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人南吮,你說我怎么就攤上這事琳彩。” “怎么了旨袒?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵汁针,是天一觀的道長。 經常有香客問我砚尽,道長施无,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任必孤,我火速辦了婚禮猾骡,結果婚禮上瑞躺,老公的妹妹穿的比我還像新娘。我一直安慰自己兴想,他們只是感情好幢哨,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嫂便,像睡著了一般捞镰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毙替,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天岸售,我揣著相機與錄音,去河邊找鬼厂画。 笑死凸丸,一個胖子當著我的面吹牛,可吹牛的內容都是我干的袱院。 我是一名探鬼主播屎慢,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忽洛!你這毒婦竟也來了腻惠?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤脐瑰,失蹤者是張志新(化名)和其女友劉穎妖枚,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體苍在,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绝页,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了寂恬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片续誉。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖初肉,靈堂內的尸體忽然破棺而出酷鸦,到底是詐尸還是另有隱情,我是刑警寧澤牙咏,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布臼隔,位于F島的核電站,受9級特大地震影響妄壶,放射性物質發(fā)生泄漏摔握。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一丁寄、第九天 我趴在偏房一處隱蔽的房頂上張望氨淌。 院中可真熱鬧泊愧,春花似錦、人聲如沸盛正。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豪筝。三九已至痰滋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間续崖,已是汗流浹背即寡。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袜刷,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓莺丑,卻偏偏與公主長得像著蟹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子梢莽,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344