应用接口抽象
Zino框架的应用接口抽象由Application trait定义,它包含一个关联类型和两个必须实现的方法:
pub trait Application {
type Routes;
fn register(self, routes: Self::Routes) -> Self;
fn run_with<T: AsyncScheduler + Send + 'static>(self, scheduler: T);
}
其中register用来注册路由,run_with用来加载异步任务并运行应用。
需要注意的是,异步任务的执行涉及到异步运行时的选择,
而zino-core本身并没有限定只能使用特定的运行时1,
所以需要实现者自行在run_with方法的实现中指定。对于同步任务,不涉及到异步运行时的选择,
我们就在Application的spawn方法中提供了默认实现。
这就是Zino框架的起点!我们只要给其他Web框架实现这个trait,就能把这个框架的功能集成到Zino中,并使应用的启动方式保存一致:
mod router;
mod schedule;
use zino::prelude::*;
fn main() {
zino::Cluster::boot()
.register(router::routes())
.register_debug(router::debug_routes())
.spawn(schedule::job_scheduler())
.run_with(schedule::async_job_scheduler())
}
目前我们已经为actix-web、axum、dioxus-desktop实现了Application trait,
它们对应的关联类型Routes分别为:
-
actix-web:引入ActixCluster类型,基于ServiceConfig来定义路由。pub type RouterConfigure = fn(cfg: &mut actix_web::web::ServiceConfig); impl Application for ActixCluster { type Routes = Vec<RouterConfigure>; } -
axum:引入AxumCluster类型,基于Router来定义路由。impl Application for AxumCluster { type Routes = Vec<axum::Router>; } -
dioxus-desktop:引入DioxusDesktop<R>类型,基于Routable泛型约束来定义路由。impl Application for DioxusDesktop<R> where R: dioxus_router::routable::Routable, <R as FromStr>::Err: Display, { type Routes = R; }
可以看到,在以上框架的Application实现中,我们并没有定义自己的路由类型,
这就使得actix-web和axum中的路由、中间件可以直接在我们的Zino框架中使用。
确保充分理解了这一点,对我们的应用开发至关重要。
1
虽然大部分情况下我们还是会优先选择tokio。