开发Aqueduct应用的最佳实践
将Dart项目分开
由于Dart是跨平台的,因此开发人员应避免将客户端应用程序项目与Aqueduct项目结合在一起。 相反,请对系统的每个方面使用具有独立项目的单个存储库。 如果有机会在平台之间共享代码(通常是在Flutter和AngularDart之间),则共享代码可以存在于同一存储库中的依赖项项目中。
多方面应用程序的典型目录结构如下所示:
application_name/
aqueduct/
flutter/
angular/
shared/
项目定义
项目是一个包含pubspec.yaml
文件和lib
目录的目录。
在服务器和客户端应用程序之间共享数据模型类型是很诱人的,但这对于除了最简单的应用程序以外的任何东西都不适用。 数据模型的四种表示形式(在数据库中,在服务器上,在网络(JSON)上和在客户端上)在行为上有足够的差异,以至于单一类型很难包含。 相反,请使用aqueduct document
生成OpenAPI规范,并使用许多开源工具之一来生成客户端数据模型类型。
使用测试驱动开发(或类似的工具)
在Aqueduct中,测试是一流的公民。aqueduct_test
包里有一些类和方法,用于初始化和运行应用程序的测试,向应用程序发出请求,并验证响应。使用像Postman或CURL这样的工具来测试概念验证代码是有价值的,但是aqueduct_test
包是专门为取代这些工具而设计的,同时随着项目的发展保留了自动测试。
一个测试套件的例子是这样的:
void main() {
final harness = new Harness()..install();
test("GET /endpoint returns 200 and a simple object", () async {
final response = await harness.agent.get("/endpoint");
expectResponse(response, 200, body: {"key": "value"});
});
}
使用bin脚本验证假设
在导入项目的bin/
目录下保留一个简单的Dart脚本文件。 在提交测试套件之前,将此文件添加到暂存器用以测试探索性代码。 不要将此文件添加到源码的版本管理中。
import 'package:myapp/myapp.dart';
Future main() async {
var whatIsThis = await someYetToBeNamedUsefullyMethod();
print("$whatIsThis");
}
从模板中创建新项目
使用 aqueduct create
来创建具有适当结构和模板的应用程序。有不同类型的应用程序的模板;使用aqueduct create list-templates
查看这些模板。
使用调试器
调试器允许你在某一行代码上停止执行正在运行的应用程序,以验证变量值,然后继续逐行执行该代码。它可以在运行测试套件或通过bin/main.dart
脚本运行应用程序时使用。
在IntelliJ IDEA中,右击任何有main
函数的文件(包括测试套件)并选择Debug
选项。使用断点(通过点击文本编辑区左侧的沟槽区域),可以在执行特定行之前停止执行。
使用建议的项目目录结构
See Aqueduct 项目结构.
将服务传递给entryPoint中的控制器
在entryPoint
中向控制器传递服务对象,并且只传递控制器将使用的服务。
class AppChannel extends ApplicationChannel {
GitHub githubService;
PostgreSQLConnection databaseConnection;
@override
Future prepare() async {
databaseConnection = new PostgreSQLConnection();
githubService = new GitHub();
}
@override
Controller get entryPoint {
final router = new Router();
router
.route("/data")
.link(() => new DBController(databaseConnection));
router
.route("/github")
.link(() => new GitHubController(githubService));
return router;
}
}
通过这样的引用,可以注入依赖于环境的依赖关系;例如,在生产、开发或测试过程中。它也避免了应用程序中的对象之间的紧密耦合。
尽量减少控制器对其依赖关系的访问;例如,当它只需要Sink
或 Stream
时,不要传递给它一个 StreamController
。
使用测试套件
测试工具会在测试套件中初始化您的应用程序。 它具有内置的行为,您可以添加到特定于应用程序的行为中。 在您的应用程序中使用测试工具的文档位于这里。
使用 config.src.yaml
使用config.src.yaml文件的约定来防止配置错误和注入测试依赖项。
了解Aqueduct 如何使用隔离
请参阅 应用程序结构.
使用ResourceController子类
子类化ResourceController提供了大多数应用程序的请求处理逻辑所使用的显着便利性、安全性和行为。 最好将此类用于非中间件控制器。
保持ApplicationChannel整洁
ApplicationChannel
应该处理初始化、路由,仅此而已。考虑将非初始化行为移到一个单独的文件中的服务对象中。
避免原始SQL查询
首选使用Aqueduct ORM。 它针对各种错误发送适当的HTTP响应,验证输入数据,并确保查询与您的数据模型匹配。
使用API参考资料
Aqueduct是一个面向对象的框架--行为由某种类型的实例来实现。对象的类型,它们的属性和行为都遵循类似的命名规则,使API更容易被发现。
Aqueduct中的许多类型都有一个与相关类型共同的前缀。例如,像 AuthServer
、AuthServerDelegate
和 AuthCode
这样的类型都是相关的,因为它们处理的是身份验证和授权。方法的命名在不同的类中是一致的(例如,asMap
是一个常见的方法名)。
在寻找解决方案的时候,看看你可以访问的对象的API参考。这些对象可能已经有了你想要实现的行为,或者有一个具有该行为的对象的引用。
谨慎使用try-catch
所有请求处理代码都包装在try-catch块中,该块将解释异常和错误并返回有意义的HTTP响应。 未知异常将产生500服务器错误响应。 通常,除非您想要的HTTP响应与针对异常返回的响应不同,否则无需使用try-catch。
如果错误对于应用程序成功启动是致命的,则不应捕获在初始化期间引发异常的代码。