從零建立一個 Dart 服務端項目

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

DartVM 的性能已經和 JVM 很是接近, 再加上和 Nodejs 同樣的異步io的處理方式, 能夠達到和 Nodejs 同級別的併發性能, 而且還有更好地運算性能, 徹底能夠替代大部分 Nodejs 的使用場景.mongodb

這篇文章將會帶你們從零建立一個 Dart 服務端項目, 本文會逐步覆蓋一下知識點:數據庫

  • 從一個空文件夾開始, 安裝依賴庫, 編寫可執行的項目
  • 編寫 API, 而且讀取 GET 請求的參數 和 POST 請求的 body
  • mongodb 或其餘數據庫的鏈接
  • 編寫請求前置中間鍵, 而且擴展 db 對象至請求的上下文
  • 進行 AOT 編譯和部署

安裝 Dart

MacOS:express

$ brew tap dart-lang/dart
 $ brew install dart
複製代碼

Windows(使用 chocolatey 安裝):跨域

c:\ choco install dart-sdk
複製代碼

或者根據 Dart官方文檔安裝bash

建立一個 Dart 項目

建立一個文件夾, 而且建立一個 pubspec.yaml 文件併發

$ mkdir your_project && cd your_project
$ touch pubspec.yaml
複製代碼

pubspec.yaml 文件內容:app

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

dependencies:
 serral: any
複製代碼

安裝依賴:koa

$ pub get
複製代碼

這裏咱們添加了一個依賴 serral 做爲 express 或 koa 的替代品進行服務端開發, 它的源碼只有 200 行, 而且約定了一套很是簡單的擴展方式, Serral API 文檔.異步

編寫你的第一個 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 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
複製代碼

序也能夠寫在最後, 不是嗎?

經過簡單的一點點代碼, 咱們已經建立了一個 Dart API 服務, 而且進行了 AOT 編譯, 讓其更合適在生產環境下運行.

但願剛開始投資 Dart 的童鞋會有些許收穫, 謝謝閱讀.

相關文章
相關標籤/搜索