运行 Finch 应用程序
一个 Finch 应用程序需要两个文件:app.dart(应用程序设置)和一个入口点——通常是生产环境使用的 bin/main.dart 或开发时使用文件监视的 lib/serve.dart。
app.dart — 应用程序设置
app.dart 创建 FinchApp 实例、注册路由并定义 main()。这是基于 Finch 示例项目的标准结构:
// lib/app.dart
import 'package:finch/finch_app.dart';
import 'package:finch/finch_tools.dart';
import 'package:finch/finch_route.dart';
import 'package:finch/finch_console.dart';
import 'route/web_route.dart';
FinchConfigs configs = FinchConfigs(
port: (env['DOMAIN_PORT'] ?? '8080').toInt(def: 8080),
domain: env['DOMAIN'] ?? 'localhost',
publicDir: pathTo(env['PUBLIC_DIR'] ?? './public'),
widgetsPath: pathTo(env['WIDGETS_PATH'] ?? './lib/widgets'),
widgetsType: env['WIDGETS_TYPE'] ?? 'j2.html',
languagePath: pathTo(env['LANGUAGE_PATH'] ?? './lib/languages'),
enableLocalDebugger: (env['ENABLE_LOCAL_DEBUGGER'] ?? false).toString().toBool,
);
final app = FinchApp(configs: configs);
void main([List<String>? args]) async {
app.addRouting(getWebRoute);
app.start(args).then((value) {
Console.p('Server started: http://localhost:${value.port}');
});
}
路由函数
路由在一个接收 Request 并返回 Future<List<FinchRoute>> 的函数中定义:
// lib/route/web_route.dart
import 'package:finch/finch_route.dart';
import '../controllers/home_controller.dart';
final homeController = HomeController();
Future<List<FinchRoute>> getWebRoute(Request rq) async {
return [
FinchRoute(
key: 'root',
path: '/',
methods: Methods.ONLY_GET,
index: homeController.index,
),
];
}
内联路由(简写)
对于简单或快速的路由,FinchApp 提供了简写方法。index 回调接收 Request 作为参数:
app
..get(
path: '/ping',
index: (rq) async => rq.renderString(text: 'pong'),
)
..post(
path: '/echo',
index: (rq) async {
var body = rq.get<String>('message', def: '');
return rq.renderString(text: body);
},
)
..postGet(
path: '/form',
index: (rq) async => rq.renderString(text: 'GET or POST'),
);
开发:使用文件监视器的 serve.dart
开发时使用 lib/serve.dart。它运行 app.dart 中的 main() 并监视 widget 和语言文件的变更,自动重新生成 Dart source map 而无需完全重启服务器:
finch serve -p lib/serve.dart
# 或
dart run lib/serve.dart
生产环境:编译为二进制
编译为独立的本地二进制文件:
finch build -a lib/app.dart -o ./build/app
./build/app
或使用提供的 Dockerfile / docker-compose。参见 Docker。
Cron 作业
使用 app.registerCron() 注册定时任务:
app.registerCron(
FinchCron(
schedule: FinchCron.evryDay(2), // 每 2 天
onCron: (index, cron) async {
// 执行清理任务
},
delayFirstMoment: true,
).start(),
);
// 标准 cron 表达式
app.registerCron(
FinchCron(
schedule: '0 * * * *', // 每小时
onCron: (index, cron) async {
// 执行每小时任务
},
).start(),
);
传递参数
始终将 args 从 main 传递给 app.start()。这使得 migrate 等 CLI 命令和自定义命令能够正常工作:
void main([List<String>? args]) async {
app.addRouting(getWebRoute);
app.start(args);
}
dart run lib/app.dart migrate --init