路由

Finch 中的路由使用 FinchRoute 对象定义,这些对象收集在一个路由函数中。路由函数通过 app.addRouting() 注册,并在每个传入请求时被调用。

路由函数

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,
    ),
  ];
}

app.dart 中注册:

app.addRouting(getWebRoute);

FinchRoute 参数

参数 类型 描述
key String 唯一路由标识符。用于生成 URL($e.routeUrl('key')
path String URL 路径段。支持 {param} 和通配符 *
methods List<String> 允许的 HTTP 方法。使用 Methods 常量
index Future<String> Function()? 处理函数(无 rq 参数;使用 Context.rq 或控制器方法)
controller Controller? 控制器实例。未设置 index 时调用其 index()
children List<FinchRoute> 嵌套子路由。路径相对于父路由
extraPath List<String> 映射到同一路由的额外路径
auth AuthController? 此路由的身份验证守卫
permissions List<String> 身份验证通过后检查的权限字符串
middlewares List<Middleware> 在处理函数之前执行的中间件链
hosts List<String> 限制到特定主机名(['*'] = 全部)
ports List<int> 限制到特定端口([] = 全部)
params Map<String, dynamic> 默认模板参数
excludePaths List<String> 从此路由排除的子路径
apiDoc Future<ApiDoc>? Function()? Swagger 的 API 文档

HTTP 方法

Methods.ONLY_GET    // ['GET']
Methods.ONLY_POST   // ['POST']
Methods.ONLY_PUT    // ['PUT']
Methods.ONLY_DELETE // ['DELETE']
Methods.GET_POST    // ['POST', 'GET']
Methods.ALL         // 所有标准 HTTP 方法

// 或自定义列表:
methods: [Methods.GET, Methods.POST, Methods.DELETE]

路径参数

使用 {name} 语法捕获 URL 段。在控制器中使用 rq.getParam('name') 读取:

FinchRoute(
  key: 'users.show',
  path: 'users/{id}',
  methods: Methods.ONLY_GET,
  index: userController.show,
),
// 在 UserController 中:
Future<String> show() async {
  var id = rq.getParam('id');
  return rq.renderData(data: {'id': id});
}

嵌套路由(children)

子路由路径相对于父路由路径:

FinchRoute(
  key: 'example',
  path: 'example',
  index: homeController.redirectToRoot,
  children: [
    FinchRoute(
      key: 'example.form.get',
      path: 'form',
      methods: Methods.ONLY_GET,
      index: homeController.exampleForm,
    ),
    FinchRoute(
      key: 'example.panel',
      path: 'panel',
      methods: Methods.ALL,
      auth: authController,
      permissions: ['admin'],
      index: homeController.exampleAuth,
    ),
  ],
),

额外路径

extraPath 将额外的 URL 前缀映射到同一路由:

FinchRoute(
  key: 'root.mysql',
  path: 'example/mysql',
  extraPath: ['api/example/mysql'],
  methods: Methods.GET_POST,
  index: homeController.exampleMysql,
),

主机和端口过滤

将路由限制到特定主机或端口:

FinchRoute(
  key: 'root.localhost',
  path: 'example/host',
  hosts: ['localhost'],
  ports: [80, 8085],
  index: homeController.renderLocalhost,
  methods: Methods.ALL,
),

身份验证守卫

附加 AuthController 来保护路由。如果 auth() 返回 false,请求在到达处理函数之前被拒绝:

FinchRoute(
  key: 'admin.panel',
  path: 'admin/panel',
  auth: AppAuthController(),
  permissions: ['admin'],
  index: adminController.panel,
),

实现详情请参阅 Auth Controller

路由缓存

使用 .cache() 扩展来缓存响应:

FinchRoute(
  key: 'root.route',
  path: 'example/route',
  methods: Methods.ONLY_GET,
  index: homeController.exampleRoute,
).cache(
  cacheDuration: Duration(minutes: 10),
  cacheType: [CacheParam.path, CacheParam.method, CacheParam.language],
  cacheSource: CacheSource.file,
),

完整详情请参阅 Route Cache

从路由键生成 URL

在模板中,使用 $e.routeUrl('key') 生成 URL:

<a href="{{ $e.routeUrl('root') }}">首页</a>
<a href="{{ $e.routeUrl('users.show', {'id': user.id}) }}">显示用户</a>