spring-web插件
spring-web是基于axum实现的
Axum是rust社区最优秀的Web框架之一,它是由tokio官方维护的一个基于hyper的子项目。Axum提供了web路由,声明式的HTTP请求解析,HTTP响应的序列化等功能,而且能够与tower生态中的中间件结合。
依赖
spring-web = { version = "<version>" }
可选的features: http2
、multipart
、ws
。
配置项
[web]
binding = "172.20.10.4" # 要绑定的网卡IP地址,默认0.0.0.0
port = 8000 # 要绑定的端口号,默认8080
connect_info = false # 是否使用客户端连接信息,默认false
graceful = true # 是否开启优雅停机, 默认false
# web中间件配置
[web.middlewares]
compression = { enable = true } # 开启压缩中间件
catch_panic = { enable = true } # 捕获handler产生的panic
logger = { enable = true, level = "info" } # 开启日志中间件
limit_payload = { enable = true, body_limit = "5MB" } # 限制请求体大小
timeout_request = { enable = true, timeout = 60000 } # 请求超时时间60s
# 跨域配置
cors = { enable = true, allow_origins = [
"*.github.io",
], allow_headers = [
"Authentication",
], allow_methods = [
"GET",
"POST",
], max_age = 60 }
# 静态资源配置
static = { enable = true, uri = "/static", path = "static", precompressed = true, fallback = "index.html" }
NOTE: 通过上面的middleware配置可以集成tower生态中提供的中间件。当然如果你对tower生态非常熟悉,也可以不启用这些middleware,通过编写代码自行配置。下面是相关的文档链接:
API接口
App实现了WebConfigurator特征,可以通过该特征指定路由配置:
1 #[tokio::main]
2 async fn main() {
3 App::new()
4 .add_plugin(SqlxPlugin)
5 .add_plugin(WebPlugin)
6 .add_router(router())
7 .run()
8 .await
9 }
10
11 fn router() -> Router {
12 Router::new().typed_route(hello_word)
13 }
14
15 #[get("/")]
16 async fn hello_word() -> impl IntoResponse {
17 "hello word"
18 }
你也可以使用auto_config
宏来实现自动配置,这个过程宏会自动将被过程宏标记的路由注册进app中:
+#[auto_config(WebConfigurator)]
#[tokio::main]
async fn main() {
App::new()
.add_plugin(SqlxPlugin)
.add_plugin(WebPlugin)
- .add_router(router())
.run()
.await
}
属性宏
上面例子中的get
是一个属性宏,spring-web
提供了八个标准HTTP METHOD的过程宏:get
、post
、patch
、put
、delete
、head
、trace
、options
。
也可以使用route
宏同时绑定多个method:
use spring_web::route;
use spring_web::axum::response::IntoResponse;
#[route("/test", method = "GET", method = "HEAD")]
async fn example() -> impl IntoResponse {
"hello world"
}
除此之外,spring还支持一个handler绑定多个路由,这需要用到routes
属性宏:
use spring_web::{routes, get, delete};
use spring_web::axum::response::IntoResponse;
#[routes]
#[get("/test")]
#[get("/test2")]
#[delete("/test")]
async fn example() -> impl IntoResponse {
"hello world"
}
提取插件注册的Component
上面的例子中SqlxPlugin
插件为我们自动注册了一个Sqlx连接池组件,我们可以使用Component
从State中提取这个连接池,Component
是一个axum的extractor。
#[get("/version")]
async fn mysql_version(Component(pool): Component<ConnectPool>) -> Result<String> {
let version = sqlx::query("select version() as version")
.fetch_one(&pool)
.await
.context("sqlx query failed")?
.get("version");
Ok(version)
}
axum也提供了其他的extractor,这些都被reexport到了spring_web::extractor
下。
读取配置
你可以用Config
抽取toml中的配置。
#[derive(Debug, Configurable, Deserialize)]
#[config_prefix = "custom"]
struct CustomConfig {
a: u32,
b: bool,
}
#[get("/config")]
async fn use_toml_config(Config(conf): Config<CustomConfig>) -> impl IntoResponse {
format!("a={}, b={}", conf.a, conf.b)
}
在你的配置文件中添加相应配置:
[custom]
a = 1
b = true
完整代码参考web-example
在Middleware中使用Component抽取注册的组件
你也可以在middleware中使用Extractor,注意需要遵循axum的规则。
use spring_web::{axum::{response::Response, middleware::Next}, extractor::{Request, Component}};
use spring_sqlx::ConnectPool;
async fn problem_middleware(Component(db): Component<ConnectPool>, request: Request, next: Next) -> Response {
// do something
let response = next.run(request).await;
response
}
完整代码参考web-middleware-example