引言
在Dart官网上看到两个现成的服务端框架,作为技术栈积累,体验了一把 Dart Frog,并整理了这篇文章。
安装 Dart Frog
首先是 dart 环境的要求 Dart Frog requires Dart ">=2.19.0 <3.0.0"
- 从 pub.dev 安装 dart_frog 命令行
dart pub global activate dart_frog_cli
安装完毕如下:
Dart Frog 创建项目
- 使用命令行创建一个 dart frog 项目
dart_frog create 项目名称
例如创建一个项目名为:dart_frog_server
目录结构如下:
使用命令行开启服务 dart_frog dev
:
打开浏览器访问能看到正常返回即表示服务已成功开启:
下面我们来创建自己的 API 路由
创建 Router
在 Dart Frog 中,我们创建的所有路由需要放置在 /routes 目录中
- 例如在 routes 目录内新建文件夹 /pages,创建一个通配符路由(通配符路由概念请看截图内注解)
请求效果如下:
- 利用通配符路由,我们可以做 Api 的逻辑分配,例如:
Future<Response> onRequest(
RequestContext context,
String action,
) async {
// 根据不同的接口路径,分配不同的api逻辑处理层
switch (action) {
case 'add':
return Response(body: 'arrival add - api');
case 'query':
return Response(body: 'arrival query - api');
default:
return Response(statusCode: 404);
}
}
获取请求内传参
通过 RequestContext 对象可获取请求内各参数:
- 获取请求类型
final method = context.request.method.value; //返回 POST/GET
- 获取 Headers
final headers = context.request.headers;
- 获取 Get 入参
final params = context.request.uri.queryParameters; //返回 Map<String, String>
- 获取 Post 入参
final body = await context.request.body();
业务开发中常使用 Post 方式传入 Json 数据作为入参,我们可以做封装提供便捷获取数据:
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传参打印出来
return Response.json(body: response);
}
访问/pages/add
请求,添加 post 入参,返回结果如下:
Middleware 中间件
Dart Frog 中的中间件允许在处理请求之前和之后执行代码。可以修改入站请求和出站响应,提供依赖项,等等!
注意:routes 目录内只能含有一个 _middleware.dart 文件,为所有入站请求执行的中间件。
1. AOP 操作(日志示例)
-
利用中间件,我们可以在每条网络请求前后添加日志:
请求http://127.0.0.1:8080/pages/add
,查看控制台打印结果:
- 如果不想自己写日志打印,dart frog 提供了一个日志打印封装
import 'package:dart_frog/dart_frog.dart';
Handler middleware(Handler handler) {
return handler.use(requestLogger());
}
重新发起请求,控制台打印结果:
2. 依赖注入
- 中间件可用于通过提供者将依赖项注入 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 {
//模拟获取异步数据
Future<String> mockFetchData() async {
await Future.delayed(const Duration(seconds: 3));
return 'mockFutureData is 李小轰';
}
}
如上代码,新建类 DataSource 提供方法模拟数据库异步查询,我们在 server 生命周期内维护了一个 dataSource 实例,而不需要在每个 request 中新建实例。
在 request 中通过 context 上下文获取 dataSource 实例:
请求结果如下:
关于 Dart Frog 部署
创建一个包含 DockerFile 的生产构建,这样你就可以部署到任何地方:
dart_frog build
demo 代码已上传 : https://github.com/liyufengrex/dart_frog_server